Am I breaking OOP practice with this architecture?












4















I have a web application. I don't believe the technology is important. The structure is an N-tier application, shown in the image on the left. There are 3 layers.



UI (MVC pattern), Business Logic Layer (BLL) and Data Access Layer (DAL)



The problem I have is my BLL is massive as it has the logic and paths through the application events call.



A typical flow through the application could be:



Event fired in UI, traverse to a method in the BLL, perform logic (possibly in multiple parts of the BLL), eventually to the DAL, back to the BLL (where likely more logic) and then return some value to the UI.



The BLL in this example is very busy and I'm thinking how to split this out. I also have the logic and the objects combined which I don't like.



enter image description here



The version on the right is my effort.



The Logic is still how the application flows between UI and DAL, but there are likely no properties... Only methods (the majority of classes in this layer could possibly be static as they don't store any state). The Poco layer is where classes exist which do have properties (such as a Person class where there would be name, age, height etc). These would have nothing to do with the flow of the application, they only store state.



The flow could be:



Even triggered from UI and passes some data to the UI layer controller (MVC). This translates the raw data and converts it into the poco model. The poco model is then passed into the Logic layer (which was the BLL) and eventually to the command query layer, potentially manipulated on the way. The Command query layer converts the POCO to a database object (which are nearly the same thing, but one is designed for persistence, the other for the front end). The item is stored and a database object is returned to the Command Query layer. It is then converted into a POCO, where it returns to the Logic layer, potentially processed further and then finally, back to the UI



The Shared logic and interfaces is where we may have persistent data, such as MaxNumberOf_X and TotalAllowed_X and all the interfaces.



Both the shared logic/interfaces and DAL are the "base" of the architecture. These know nothing about the outside world.



Everything knows about poco other than the shared logic/interfaces and DAL.



The flow is still very similar to the first example, but it's made each layer more responsible for 1 thing (be it state, flow or anything else)... but am I breaking OOP with this approach?



An example to demo the Logic and Poco could be:



public class LogicClass
{
private ICommandQueryObject cmdQuery;
public PocoA Method1(PocoB pocoB)
{
return cmdQuery.Save(pocoB);
}

/*This has no state objects, only ways to communicate with other
layers such as the cmdQuery. Everything else is just function
calls to allow flow via the program */
public PocoA Method2(PocoB pocoB)
{
pocoB.UpdateState("world");
return Method1(pocoB);
}

}

public struct PocoX
{
public string DataA {get;set;}
public int DataB {get;set;}
public int DataC {get;set;}

/*This simply returns something that is part of this class.
Everything is self-contained to this class. It doesn't call
trying to directly communicate with databases etc*/
public int GetValue()
{

return DataB * DataC;
}

/*This simply sets something that is part of this class.
Everything is self-contained to this class.
It doesn't call trying to directly communicate with databases etc*/
public void UpdateState(string input)
{
DataA += input;
}
}









share|improve this question

























  • I don't see anything fundamentally wrong with your architecture as you've currently described it.

    – Robert Harvey
    3 hours ago






  • 3





    There isn't enough functional detail in your code example to provide any further insight. Foobar examples seldom provide sufficient illustration.

    – Robert Harvey
    3 hours ago


















4















I have a web application. I don't believe the technology is important. The structure is an N-tier application, shown in the image on the left. There are 3 layers.



UI (MVC pattern), Business Logic Layer (BLL) and Data Access Layer (DAL)



The problem I have is my BLL is massive as it has the logic and paths through the application events call.



A typical flow through the application could be:



Event fired in UI, traverse to a method in the BLL, perform logic (possibly in multiple parts of the BLL), eventually to the DAL, back to the BLL (where likely more logic) and then return some value to the UI.



The BLL in this example is very busy and I'm thinking how to split this out. I also have the logic and the objects combined which I don't like.



enter image description here



The version on the right is my effort.



The Logic is still how the application flows between UI and DAL, but there are likely no properties... Only methods (the majority of classes in this layer could possibly be static as they don't store any state). The Poco layer is where classes exist which do have properties (such as a Person class where there would be name, age, height etc). These would have nothing to do with the flow of the application, they only store state.



The flow could be:



Even triggered from UI and passes some data to the UI layer controller (MVC). This translates the raw data and converts it into the poco model. The poco model is then passed into the Logic layer (which was the BLL) and eventually to the command query layer, potentially manipulated on the way. The Command query layer converts the POCO to a database object (which are nearly the same thing, but one is designed for persistence, the other for the front end). The item is stored and a database object is returned to the Command Query layer. It is then converted into a POCO, where it returns to the Logic layer, potentially processed further and then finally, back to the UI



The Shared logic and interfaces is where we may have persistent data, such as MaxNumberOf_X and TotalAllowed_X and all the interfaces.



Both the shared logic/interfaces and DAL are the "base" of the architecture. These know nothing about the outside world.



Everything knows about poco other than the shared logic/interfaces and DAL.



The flow is still very similar to the first example, but it's made each layer more responsible for 1 thing (be it state, flow or anything else)... but am I breaking OOP with this approach?



An example to demo the Logic and Poco could be:



public class LogicClass
{
private ICommandQueryObject cmdQuery;
public PocoA Method1(PocoB pocoB)
{
return cmdQuery.Save(pocoB);
}

/*This has no state objects, only ways to communicate with other
layers such as the cmdQuery. Everything else is just function
calls to allow flow via the program */
public PocoA Method2(PocoB pocoB)
{
pocoB.UpdateState("world");
return Method1(pocoB);
}

}

public struct PocoX
{
public string DataA {get;set;}
public int DataB {get;set;}
public int DataC {get;set;}

/*This simply returns something that is part of this class.
Everything is self-contained to this class. It doesn't call
trying to directly communicate with databases etc*/
public int GetValue()
{

return DataB * DataC;
}

/*This simply sets something that is part of this class.
Everything is self-contained to this class.
It doesn't call trying to directly communicate with databases etc*/
public void UpdateState(string input)
{
DataA += input;
}
}









share|improve this question

























  • I don't see anything fundamentally wrong with your architecture as you've currently described it.

    – Robert Harvey
    3 hours ago






  • 3





    There isn't enough functional detail in your code example to provide any further insight. Foobar examples seldom provide sufficient illustration.

    – Robert Harvey
    3 hours ago
















4












4








4


2






I have a web application. I don't believe the technology is important. The structure is an N-tier application, shown in the image on the left. There are 3 layers.



UI (MVC pattern), Business Logic Layer (BLL) and Data Access Layer (DAL)



The problem I have is my BLL is massive as it has the logic and paths through the application events call.



A typical flow through the application could be:



Event fired in UI, traverse to a method in the BLL, perform logic (possibly in multiple parts of the BLL), eventually to the DAL, back to the BLL (where likely more logic) and then return some value to the UI.



The BLL in this example is very busy and I'm thinking how to split this out. I also have the logic and the objects combined which I don't like.



enter image description here



The version on the right is my effort.



The Logic is still how the application flows between UI and DAL, but there are likely no properties... Only methods (the majority of classes in this layer could possibly be static as they don't store any state). The Poco layer is where classes exist which do have properties (such as a Person class where there would be name, age, height etc). These would have nothing to do with the flow of the application, they only store state.



The flow could be:



Even triggered from UI and passes some data to the UI layer controller (MVC). This translates the raw data and converts it into the poco model. The poco model is then passed into the Logic layer (which was the BLL) and eventually to the command query layer, potentially manipulated on the way. The Command query layer converts the POCO to a database object (which are nearly the same thing, but one is designed for persistence, the other for the front end). The item is stored and a database object is returned to the Command Query layer. It is then converted into a POCO, where it returns to the Logic layer, potentially processed further and then finally, back to the UI



The Shared logic and interfaces is where we may have persistent data, such as MaxNumberOf_X and TotalAllowed_X and all the interfaces.



Both the shared logic/interfaces and DAL are the "base" of the architecture. These know nothing about the outside world.



Everything knows about poco other than the shared logic/interfaces and DAL.



The flow is still very similar to the first example, but it's made each layer more responsible for 1 thing (be it state, flow or anything else)... but am I breaking OOP with this approach?



An example to demo the Logic and Poco could be:



public class LogicClass
{
private ICommandQueryObject cmdQuery;
public PocoA Method1(PocoB pocoB)
{
return cmdQuery.Save(pocoB);
}

/*This has no state objects, only ways to communicate with other
layers such as the cmdQuery. Everything else is just function
calls to allow flow via the program */
public PocoA Method2(PocoB pocoB)
{
pocoB.UpdateState("world");
return Method1(pocoB);
}

}

public struct PocoX
{
public string DataA {get;set;}
public int DataB {get;set;}
public int DataC {get;set;}

/*This simply returns something that is part of this class.
Everything is self-contained to this class. It doesn't call
trying to directly communicate with databases etc*/
public int GetValue()
{

return DataB * DataC;
}

/*This simply sets something that is part of this class.
Everything is self-contained to this class.
It doesn't call trying to directly communicate with databases etc*/
public void UpdateState(string input)
{
DataA += input;
}
}









share|improve this question
















I have a web application. I don't believe the technology is important. The structure is an N-tier application, shown in the image on the left. There are 3 layers.



UI (MVC pattern), Business Logic Layer (BLL) and Data Access Layer (DAL)



The problem I have is my BLL is massive as it has the logic and paths through the application events call.



A typical flow through the application could be:



Event fired in UI, traverse to a method in the BLL, perform logic (possibly in multiple parts of the BLL), eventually to the DAL, back to the BLL (where likely more logic) and then return some value to the UI.



The BLL in this example is very busy and I'm thinking how to split this out. I also have the logic and the objects combined which I don't like.



enter image description here



The version on the right is my effort.



The Logic is still how the application flows between UI and DAL, but there are likely no properties... Only methods (the majority of classes in this layer could possibly be static as they don't store any state). The Poco layer is where classes exist which do have properties (such as a Person class where there would be name, age, height etc). These would have nothing to do with the flow of the application, they only store state.



The flow could be:



Even triggered from UI and passes some data to the UI layer controller (MVC). This translates the raw data and converts it into the poco model. The poco model is then passed into the Logic layer (which was the BLL) and eventually to the command query layer, potentially manipulated on the way. The Command query layer converts the POCO to a database object (which are nearly the same thing, but one is designed for persistence, the other for the front end). The item is stored and a database object is returned to the Command Query layer. It is then converted into a POCO, where it returns to the Logic layer, potentially processed further and then finally, back to the UI



The Shared logic and interfaces is where we may have persistent data, such as MaxNumberOf_X and TotalAllowed_X and all the interfaces.



Both the shared logic/interfaces and DAL are the "base" of the architecture. These know nothing about the outside world.



Everything knows about poco other than the shared logic/interfaces and DAL.



The flow is still very similar to the first example, but it's made each layer more responsible for 1 thing (be it state, flow or anything else)... but am I breaking OOP with this approach?



An example to demo the Logic and Poco could be:



public class LogicClass
{
private ICommandQueryObject cmdQuery;
public PocoA Method1(PocoB pocoB)
{
return cmdQuery.Save(pocoB);
}

/*This has no state objects, only ways to communicate with other
layers such as the cmdQuery. Everything else is just function
calls to allow flow via the program */
public PocoA Method2(PocoB pocoB)
{
pocoB.UpdateState("world");
return Method1(pocoB);
}

}

public struct PocoX
{
public string DataA {get;set;}
public int DataB {get;set;}
public int DataC {get;set;}

/*This simply returns something that is part of this class.
Everything is self-contained to this class. It doesn't call
trying to directly communicate with databases etc*/
public int GetValue()
{

return DataB * DataC;
}

/*This simply sets something that is part of this class.
Everything is self-contained to this class.
It doesn't call trying to directly communicate with databases etc*/
public void UpdateState(string input)
{
DataA += input;
}
}






object-oriented architecture






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 3 hours ago









Laiv

6,95811241




6,95811241










asked 4 hours ago









MyDaftQuestionsMyDaftQuestions

7982810




7982810













  • I don't see anything fundamentally wrong with your architecture as you've currently described it.

    – Robert Harvey
    3 hours ago






  • 3





    There isn't enough functional detail in your code example to provide any further insight. Foobar examples seldom provide sufficient illustration.

    – Robert Harvey
    3 hours ago





















  • I don't see anything fundamentally wrong with your architecture as you've currently described it.

    – Robert Harvey
    3 hours ago






  • 3





    There isn't enough functional detail in your code example to provide any further insight. Foobar examples seldom provide sufficient illustration.

    – Robert Harvey
    3 hours ago



















I don't see anything fundamentally wrong with your architecture as you've currently described it.

– Robert Harvey
3 hours ago





I don't see anything fundamentally wrong with your architecture as you've currently described it.

– Robert Harvey
3 hours ago




3




3





There isn't enough functional detail in your code example to provide any further insight. Foobar examples seldom provide sufficient illustration.

– Robert Harvey
3 hours ago







There isn't enough functional detail in your code example to provide any further insight. Foobar examples seldom provide sufficient illustration.

– Robert Harvey
3 hours ago












3 Answers
3






active

oldest

votes


















5














Yes, you are very likely breaking core OOP concepts. However don't feel bad, people do this all the time, it doesn't mean that your architecture is "wrong". I would say it is probably less maintainable than a proper OO design, but this is rather subjective and not your question anyway. (Here is an article of mine criticizing the n-tier architecture in general).



Reasoning: The most basic concept of OOP is that data and logic form a single unit (an object). Although this is a very simplistic and mechanical statement, even so, it is not really followed in your design (if I understand you correctly). You are quite clearly separating most of the data from most of the logic. Having stateless (static-like) methods for example is called "procedures", and are generally antithetic to OOP.



There are of course always exceptions, but this design violates these things as a rule.



Again, I would like to stress "violates OOP" != "wrong", so this is not necessarily a value judgement. It all depends on your architecture constraints, maintainability use-cases, requirements, etc.






share|improve this answer



















  • 1





    Have an upvote, this is a good answer, if I were writing my own, I would copy & paste this, but also add that, if you find your self not writing OOP code, perhaps you should consider a non-OOP language as it comes with a lot of extra overhead that you can do without if you aren't using it

    – TheCatWhisperer
    1 hour ago



















5














One of the core principles of Functional Programming is pure functions.



One of the core principles of Object Oriented Programming is putting functions together with the data they act on.



Both of these core principles fall away when your application has to communicate with the outside world. Indeed you can only be true to these ideals in a specially prepared space in your system. Not every line of your code must meet these ideals. But if no line of your code meets these ideals you can't really claim to be using OOP or FP.



So it's OK to have data only "objects" that you fling around because you need them to cross a boundary that you simply can't refactor to move the interested code across. Just know that isn't OOP. That's reality. OOP is when, once inside that boundary you gather all the logic that acts on that data into one place.



Not that you have to do that either. OOP isn't all things to all people. It is what it is. Just don't claim something follows OOP when it doesn't or you're going to confuse people trying to maintain your code.



Your POCO's seem to have business logic in them just fine so I wouldn't worry about to much about being anemic. What does concern me is they all seem very mutable. Remember that getters and setters don't provide real encapsulation. If your POCO is headed for that boundry then fine. Just understand this isn't giving you the full benefits of a real encapsulated OOP object. Some call this a Data Transfer Object or DTO.



A trick I've used successfully is to craft OOP objects that eat DTO's. I use the DTO as a parameter object. My constructor reads state from it (read as defensive copy) and tosses it aside. Now I've got a fully encapsulated and immutable version of the DTO. I can move all methods concerned with this data can be moved here provided they're on this side of that boundary.



I don't provide getters or setters. I follow tell, don't ask. You call my methods and they go do what needs doing. They likely don't even tell you what they did. They just do it.



Now eventually something, somewhere is going to run into another boundary and this all falls apart again. That's fine. Spin up another DTO and toss it over the wall.



This is the essence of what the ports and adapters architecture is all about. I've been reading about it from a functional perspective. Maybe it'll interest you too.






share|improve this answer

































    1














    If I read your explanation correctly your objects look a bit like this: (tricky without context)



    public class LogicClass
    {
    private ICommandQueryObject cmdQuery;
    public PocoA Method(PocoB pocoB) { ... }
    }

    public class PocoX
    {
    public string DataA {get;set;}
    public int DataB {get;set;}
    ... etc
    }


    In that your Poco classes contain only data and your Logic classes contain the methods which act on that data; yes, you have broken the principles of "Classic OOP"



    Again, it's hard to tell from your generalised description, but I would hazard that what you have written could be categorized as Anemic Domain Model.



    I don't think this is a particularly bad approach, nor, if you consider your Poco's as structs does it nescarly break OOP in the more specific sense. In that your Objects are now the LogicClasses. Indeed if you make your Pocos immutable the design could be considered quite Functional.



    However, when you reference Shared Logic, Pocos that are almost but not the same and statics I start to worry about the detail of your design.






    share|improve this answer
























    • I've added to my post, essentially copying your example. Sorry ti wasn't clear to start with

      – MyDaftQuestions
      3 hours ago






    • 1





      what I mean is, if you told us what the application does it would be easier to write examples. Instead of LogicClass you could have PaymentProvider or whatever

      – Ewan
      2 hours ago












    Your Answer








    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "131"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: false,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsoftwareengineering.stackexchange.com%2fquestions%2f389638%2fam-i-breaking-oop-practice-with-this-architecture%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    3 Answers
    3






    active

    oldest

    votes








    3 Answers
    3






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    5














    Yes, you are very likely breaking core OOP concepts. However don't feel bad, people do this all the time, it doesn't mean that your architecture is "wrong". I would say it is probably less maintainable than a proper OO design, but this is rather subjective and not your question anyway. (Here is an article of mine criticizing the n-tier architecture in general).



    Reasoning: The most basic concept of OOP is that data and logic form a single unit (an object). Although this is a very simplistic and mechanical statement, even so, it is not really followed in your design (if I understand you correctly). You are quite clearly separating most of the data from most of the logic. Having stateless (static-like) methods for example is called "procedures", and are generally antithetic to OOP.



    There are of course always exceptions, but this design violates these things as a rule.



    Again, I would like to stress "violates OOP" != "wrong", so this is not necessarily a value judgement. It all depends on your architecture constraints, maintainability use-cases, requirements, etc.






    share|improve this answer



















    • 1





      Have an upvote, this is a good answer, if I were writing my own, I would copy & paste this, but also add that, if you find your self not writing OOP code, perhaps you should consider a non-OOP language as it comes with a lot of extra overhead that you can do without if you aren't using it

      – TheCatWhisperer
      1 hour ago
















    5














    Yes, you are very likely breaking core OOP concepts. However don't feel bad, people do this all the time, it doesn't mean that your architecture is "wrong". I would say it is probably less maintainable than a proper OO design, but this is rather subjective and not your question anyway. (Here is an article of mine criticizing the n-tier architecture in general).



    Reasoning: The most basic concept of OOP is that data and logic form a single unit (an object). Although this is a very simplistic and mechanical statement, even so, it is not really followed in your design (if I understand you correctly). You are quite clearly separating most of the data from most of the logic. Having stateless (static-like) methods for example is called "procedures", and are generally antithetic to OOP.



    There are of course always exceptions, but this design violates these things as a rule.



    Again, I would like to stress "violates OOP" != "wrong", so this is not necessarily a value judgement. It all depends on your architecture constraints, maintainability use-cases, requirements, etc.






    share|improve this answer



















    • 1





      Have an upvote, this is a good answer, if I were writing my own, I would copy & paste this, but also add that, if you find your self not writing OOP code, perhaps you should consider a non-OOP language as it comes with a lot of extra overhead that you can do without if you aren't using it

      – TheCatWhisperer
      1 hour ago














    5












    5








    5







    Yes, you are very likely breaking core OOP concepts. However don't feel bad, people do this all the time, it doesn't mean that your architecture is "wrong". I would say it is probably less maintainable than a proper OO design, but this is rather subjective and not your question anyway. (Here is an article of mine criticizing the n-tier architecture in general).



    Reasoning: The most basic concept of OOP is that data and logic form a single unit (an object). Although this is a very simplistic and mechanical statement, even so, it is not really followed in your design (if I understand you correctly). You are quite clearly separating most of the data from most of the logic. Having stateless (static-like) methods for example is called "procedures", and are generally antithetic to OOP.



    There are of course always exceptions, but this design violates these things as a rule.



    Again, I would like to stress "violates OOP" != "wrong", so this is not necessarily a value judgement. It all depends on your architecture constraints, maintainability use-cases, requirements, etc.






    share|improve this answer













    Yes, you are very likely breaking core OOP concepts. However don't feel bad, people do this all the time, it doesn't mean that your architecture is "wrong". I would say it is probably less maintainable than a proper OO design, but this is rather subjective and not your question anyway. (Here is an article of mine criticizing the n-tier architecture in general).



    Reasoning: The most basic concept of OOP is that data and logic form a single unit (an object). Although this is a very simplistic and mechanical statement, even so, it is not really followed in your design (if I understand you correctly). You are quite clearly separating most of the data from most of the logic. Having stateless (static-like) methods for example is called "procedures", and are generally antithetic to OOP.



    There are of course always exceptions, but this design violates these things as a rule.



    Again, I would like to stress "violates OOP" != "wrong", so this is not necessarily a value judgement. It all depends on your architecture constraints, maintainability use-cases, requirements, etc.







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered 3 hours ago









    Robert BräutigamRobert Bräutigam

    1,934611




    1,934611








    • 1





      Have an upvote, this is a good answer, if I were writing my own, I would copy & paste this, but also add that, if you find your self not writing OOP code, perhaps you should consider a non-OOP language as it comes with a lot of extra overhead that you can do without if you aren't using it

      – TheCatWhisperer
      1 hour ago














    • 1





      Have an upvote, this is a good answer, if I were writing my own, I would copy & paste this, but also add that, if you find your self not writing OOP code, perhaps you should consider a non-OOP language as it comes with a lot of extra overhead that you can do without if you aren't using it

      – TheCatWhisperer
      1 hour ago








    1




    1





    Have an upvote, this is a good answer, if I were writing my own, I would copy & paste this, but also add that, if you find your self not writing OOP code, perhaps you should consider a non-OOP language as it comes with a lot of extra overhead that you can do without if you aren't using it

    – TheCatWhisperer
    1 hour ago





    Have an upvote, this is a good answer, if I were writing my own, I would copy & paste this, but also add that, if you find your self not writing OOP code, perhaps you should consider a non-OOP language as it comes with a lot of extra overhead that you can do without if you aren't using it

    – TheCatWhisperer
    1 hour ago













    5














    One of the core principles of Functional Programming is pure functions.



    One of the core principles of Object Oriented Programming is putting functions together with the data they act on.



    Both of these core principles fall away when your application has to communicate with the outside world. Indeed you can only be true to these ideals in a specially prepared space in your system. Not every line of your code must meet these ideals. But if no line of your code meets these ideals you can't really claim to be using OOP or FP.



    So it's OK to have data only "objects" that you fling around because you need them to cross a boundary that you simply can't refactor to move the interested code across. Just know that isn't OOP. That's reality. OOP is when, once inside that boundary you gather all the logic that acts on that data into one place.



    Not that you have to do that either. OOP isn't all things to all people. It is what it is. Just don't claim something follows OOP when it doesn't or you're going to confuse people trying to maintain your code.



    Your POCO's seem to have business logic in them just fine so I wouldn't worry about to much about being anemic. What does concern me is they all seem very mutable. Remember that getters and setters don't provide real encapsulation. If your POCO is headed for that boundry then fine. Just understand this isn't giving you the full benefits of a real encapsulated OOP object. Some call this a Data Transfer Object or DTO.



    A trick I've used successfully is to craft OOP objects that eat DTO's. I use the DTO as a parameter object. My constructor reads state from it (read as defensive copy) and tosses it aside. Now I've got a fully encapsulated and immutable version of the DTO. I can move all methods concerned with this data can be moved here provided they're on this side of that boundary.



    I don't provide getters or setters. I follow tell, don't ask. You call my methods and they go do what needs doing. They likely don't even tell you what they did. They just do it.



    Now eventually something, somewhere is going to run into another boundary and this all falls apart again. That's fine. Spin up another DTO and toss it over the wall.



    This is the essence of what the ports and adapters architecture is all about. I've been reading about it from a functional perspective. Maybe it'll interest you too.






    share|improve this answer






























      5














      One of the core principles of Functional Programming is pure functions.



      One of the core principles of Object Oriented Programming is putting functions together with the data they act on.



      Both of these core principles fall away when your application has to communicate with the outside world. Indeed you can only be true to these ideals in a specially prepared space in your system. Not every line of your code must meet these ideals. But if no line of your code meets these ideals you can't really claim to be using OOP or FP.



      So it's OK to have data only "objects" that you fling around because you need them to cross a boundary that you simply can't refactor to move the interested code across. Just know that isn't OOP. That's reality. OOP is when, once inside that boundary you gather all the logic that acts on that data into one place.



      Not that you have to do that either. OOP isn't all things to all people. It is what it is. Just don't claim something follows OOP when it doesn't or you're going to confuse people trying to maintain your code.



      Your POCO's seem to have business logic in them just fine so I wouldn't worry about to much about being anemic. What does concern me is they all seem very mutable. Remember that getters and setters don't provide real encapsulation. If your POCO is headed for that boundry then fine. Just understand this isn't giving you the full benefits of a real encapsulated OOP object. Some call this a Data Transfer Object or DTO.



      A trick I've used successfully is to craft OOP objects that eat DTO's. I use the DTO as a parameter object. My constructor reads state from it (read as defensive copy) and tosses it aside. Now I've got a fully encapsulated and immutable version of the DTO. I can move all methods concerned with this data can be moved here provided they're on this side of that boundary.



      I don't provide getters or setters. I follow tell, don't ask. You call my methods and they go do what needs doing. They likely don't even tell you what they did. They just do it.



      Now eventually something, somewhere is going to run into another boundary and this all falls apart again. That's fine. Spin up another DTO and toss it over the wall.



      This is the essence of what the ports and adapters architecture is all about. I've been reading about it from a functional perspective. Maybe it'll interest you too.






      share|improve this answer




























        5












        5








        5







        One of the core principles of Functional Programming is pure functions.



        One of the core principles of Object Oriented Programming is putting functions together with the data they act on.



        Both of these core principles fall away when your application has to communicate with the outside world. Indeed you can only be true to these ideals in a specially prepared space in your system. Not every line of your code must meet these ideals. But if no line of your code meets these ideals you can't really claim to be using OOP or FP.



        So it's OK to have data only "objects" that you fling around because you need them to cross a boundary that you simply can't refactor to move the interested code across. Just know that isn't OOP. That's reality. OOP is when, once inside that boundary you gather all the logic that acts on that data into one place.



        Not that you have to do that either. OOP isn't all things to all people. It is what it is. Just don't claim something follows OOP when it doesn't or you're going to confuse people trying to maintain your code.



        Your POCO's seem to have business logic in them just fine so I wouldn't worry about to much about being anemic. What does concern me is they all seem very mutable. Remember that getters and setters don't provide real encapsulation. If your POCO is headed for that boundry then fine. Just understand this isn't giving you the full benefits of a real encapsulated OOP object. Some call this a Data Transfer Object or DTO.



        A trick I've used successfully is to craft OOP objects that eat DTO's. I use the DTO as a parameter object. My constructor reads state from it (read as defensive copy) and tosses it aside. Now I've got a fully encapsulated and immutable version of the DTO. I can move all methods concerned with this data can be moved here provided they're on this side of that boundary.



        I don't provide getters or setters. I follow tell, don't ask. You call my methods and they go do what needs doing. They likely don't even tell you what they did. They just do it.



        Now eventually something, somewhere is going to run into another boundary and this all falls apart again. That's fine. Spin up another DTO and toss it over the wall.



        This is the essence of what the ports and adapters architecture is all about. I've been reading about it from a functional perspective. Maybe it'll interest you too.






        share|improve this answer















        One of the core principles of Functional Programming is pure functions.



        One of the core principles of Object Oriented Programming is putting functions together with the data they act on.



        Both of these core principles fall away when your application has to communicate with the outside world. Indeed you can only be true to these ideals in a specially prepared space in your system. Not every line of your code must meet these ideals. But if no line of your code meets these ideals you can't really claim to be using OOP or FP.



        So it's OK to have data only "objects" that you fling around because you need them to cross a boundary that you simply can't refactor to move the interested code across. Just know that isn't OOP. That's reality. OOP is when, once inside that boundary you gather all the logic that acts on that data into one place.



        Not that you have to do that either. OOP isn't all things to all people. It is what it is. Just don't claim something follows OOP when it doesn't or you're going to confuse people trying to maintain your code.



        Your POCO's seem to have business logic in them just fine so I wouldn't worry about to much about being anemic. What does concern me is they all seem very mutable. Remember that getters and setters don't provide real encapsulation. If your POCO is headed for that boundry then fine. Just understand this isn't giving you the full benefits of a real encapsulated OOP object. Some call this a Data Transfer Object or DTO.



        A trick I've used successfully is to craft OOP objects that eat DTO's. I use the DTO as a parameter object. My constructor reads state from it (read as defensive copy) and tosses it aside. Now I've got a fully encapsulated and immutable version of the DTO. I can move all methods concerned with this data can be moved here provided they're on this side of that boundary.



        I don't provide getters or setters. I follow tell, don't ask. You call my methods and they go do what needs doing. They likely don't even tell you what they did. They just do it.



        Now eventually something, somewhere is going to run into another boundary and this all falls apart again. That's fine. Spin up another DTO and toss it over the wall.



        This is the essence of what the ports and adapters architecture is all about. I've been reading about it from a functional perspective. Maybe it'll interest you too.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited 1 hour ago

























        answered 1 hour ago









        candied_orangecandied_orange

        54.9k17104191




        54.9k17104191























            1














            If I read your explanation correctly your objects look a bit like this: (tricky without context)



            public class LogicClass
            {
            private ICommandQueryObject cmdQuery;
            public PocoA Method(PocoB pocoB) { ... }
            }

            public class PocoX
            {
            public string DataA {get;set;}
            public int DataB {get;set;}
            ... etc
            }


            In that your Poco classes contain only data and your Logic classes contain the methods which act on that data; yes, you have broken the principles of "Classic OOP"



            Again, it's hard to tell from your generalised description, but I would hazard that what you have written could be categorized as Anemic Domain Model.



            I don't think this is a particularly bad approach, nor, if you consider your Poco's as structs does it nescarly break OOP in the more specific sense. In that your Objects are now the LogicClasses. Indeed if you make your Pocos immutable the design could be considered quite Functional.



            However, when you reference Shared Logic, Pocos that are almost but not the same and statics I start to worry about the detail of your design.






            share|improve this answer
























            • I've added to my post, essentially copying your example. Sorry ti wasn't clear to start with

              – MyDaftQuestions
              3 hours ago






            • 1





              what I mean is, if you told us what the application does it would be easier to write examples. Instead of LogicClass you could have PaymentProvider or whatever

              – Ewan
              2 hours ago
















            1














            If I read your explanation correctly your objects look a bit like this: (tricky without context)



            public class LogicClass
            {
            private ICommandQueryObject cmdQuery;
            public PocoA Method(PocoB pocoB) { ... }
            }

            public class PocoX
            {
            public string DataA {get;set;}
            public int DataB {get;set;}
            ... etc
            }


            In that your Poco classes contain only data and your Logic classes contain the methods which act on that data; yes, you have broken the principles of "Classic OOP"



            Again, it's hard to tell from your generalised description, but I would hazard that what you have written could be categorized as Anemic Domain Model.



            I don't think this is a particularly bad approach, nor, if you consider your Poco's as structs does it nescarly break OOP in the more specific sense. In that your Objects are now the LogicClasses. Indeed if you make your Pocos immutable the design could be considered quite Functional.



            However, when you reference Shared Logic, Pocos that are almost but not the same and statics I start to worry about the detail of your design.






            share|improve this answer
























            • I've added to my post, essentially copying your example. Sorry ti wasn't clear to start with

              – MyDaftQuestions
              3 hours ago






            • 1





              what I mean is, if you told us what the application does it would be easier to write examples. Instead of LogicClass you could have PaymentProvider or whatever

              – Ewan
              2 hours ago














            1












            1








            1







            If I read your explanation correctly your objects look a bit like this: (tricky without context)



            public class LogicClass
            {
            private ICommandQueryObject cmdQuery;
            public PocoA Method(PocoB pocoB) { ... }
            }

            public class PocoX
            {
            public string DataA {get;set;}
            public int DataB {get;set;}
            ... etc
            }


            In that your Poco classes contain only data and your Logic classes contain the methods which act on that data; yes, you have broken the principles of "Classic OOP"



            Again, it's hard to tell from your generalised description, but I would hazard that what you have written could be categorized as Anemic Domain Model.



            I don't think this is a particularly bad approach, nor, if you consider your Poco's as structs does it nescarly break OOP in the more specific sense. In that your Objects are now the LogicClasses. Indeed if you make your Pocos immutable the design could be considered quite Functional.



            However, when you reference Shared Logic, Pocos that are almost but not the same and statics I start to worry about the detail of your design.






            share|improve this answer













            If I read your explanation correctly your objects look a bit like this: (tricky without context)



            public class LogicClass
            {
            private ICommandQueryObject cmdQuery;
            public PocoA Method(PocoB pocoB) { ... }
            }

            public class PocoX
            {
            public string DataA {get;set;}
            public int DataB {get;set;}
            ... etc
            }


            In that your Poco classes contain only data and your Logic classes contain the methods which act on that data; yes, you have broken the principles of "Classic OOP"



            Again, it's hard to tell from your generalised description, but I would hazard that what you have written could be categorized as Anemic Domain Model.



            I don't think this is a particularly bad approach, nor, if you consider your Poco's as structs does it nescarly break OOP in the more specific sense. In that your Objects are now the LogicClasses. Indeed if you make your Pocos immutable the design could be considered quite Functional.



            However, when you reference Shared Logic, Pocos that are almost but not the same and statics I start to worry about the detail of your design.







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered 4 hours ago









            EwanEwan

            42.8k33695




            42.8k33695













            • I've added to my post, essentially copying your example. Sorry ti wasn't clear to start with

              – MyDaftQuestions
              3 hours ago






            • 1





              what I mean is, if you told us what the application does it would be easier to write examples. Instead of LogicClass you could have PaymentProvider or whatever

              – Ewan
              2 hours ago



















            • I've added to my post, essentially copying your example. Sorry ti wasn't clear to start with

              – MyDaftQuestions
              3 hours ago






            • 1





              what I mean is, if you told us what the application does it would be easier to write examples. Instead of LogicClass you could have PaymentProvider or whatever

              – Ewan
              2 hours ago

















            I've added to my post, essentially copying your example. Sorry ti wasn't clear to start with

            – MyDaftQuestions
            3 hours ago





            I've added to my post, essentially copying your example. Sorry ti wasn't clear to start with

            – MyDaftQuestions
            3 hours ago




            1




            1





            what I mean is, if you told us what the application does it would be easier to write examples. Instead of LogicClass you could have PaymentProvider or whatever

            – Ewan
            2 hours ago





            what I mean is, if you told us what the application does it would be easier to write examples. Instead of LogicClass you could have PaymentProvider or whatever

            – Ewan
            2 hours ago


















            draft saved

            draft discarded




















































            Thanks for contributing an answer to Software Engineering Stack Exchange!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsoftwareengineering.stackexchange.com%2fquestions%2f389638%2fam-i-breaking-oop-practice-with-this-architecture%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            flock() on closed filehandle LOCK_FILE at /usr/bin/apt-mirror

            Mangá

            Eduardo VII do Reino Unido