How to avoid Anemic Domain Models and maintain Separation of Concerns? - language-agnostic

It seems that the decision to make your objects fully cognizant of their roles within the system, and still avoid having too many dependencies within the domain model on the database, and service layers?
For example: Say that I've got an entity with a revision history, and several "lookup tables" that the data references, your entity object should have methods to get the details from some of the lookup tables, whether by providing access to the lookup table rows, or by delegating methods down to them, but in order to do so it depends on the database layer to read the data from those rows. Also, when the entity is saved, It needs to know not only how to save itself, but also to save entries into the revision history. Is it necessary to pass references to dozens of different data layer objects and service objects to the model object? This seems like it makes the logic far more complex to understand than just passing back and forth thin models to service layer objects, but I've heard many "wise men" recommending this sort of structure.

Really really good question. I have spent quite a bit of time thinking about such topics.
You demonstrate great insight by noting the tension between an expressive domain model and separation of concerns. This is much like the tension in the question I asked about Tell Don't Ask and Single Responsibility Principle.
Here is my view on the topic.
A domain model is anemic because it contains no domain logic. Other objects get and set data using an anemic domain object. What you describe doesn't sound like domain logic to me. It might be, but generally, look-up tables and other technical language is most likely terms that mean something to us but not necessarily anything to the customers. If this is incorrect, please clarify.
Anyway, the construction and persistence of domain objects shouldn't be contained in the domain objects themselves because that isn't domain logic.
So to answer the question, no, you shouldn't inject a whole bunch of non-domain objects/concepts like lookup tables and other infrastructure details. This is a leak of one concern into another. The Factory and Repository patterns from Domain-Driven Design are best suited to keep these concerns apart from the domain model itself.
But note that if you don't have any domain logic, then you will end up with anemic domain objects, i.e. bags of brainless getters and setters, which is how some shops claim to do SOA / service layers.
So how do you get the best of both worlds? How do you focus your domain objects only domain logic, while keeping UI, construction, persistence, etc. out of the way? I recommend you use a technique like Double Dispatch, or some form of restricted method access.
Here's an example of Double Dispatch. Say you have this line of code:
entity.saveIn(repository);
In your question, saveIn() would have all sorts of knowledge about the data layer. Using Double Dispatch, saveIn() does this:
repository.saveEntity(this.foo, this.bar, this.baz);
And the saveEntity() method of the repository has all of the knowledge of how to save in the data layer, as it should.
In addition to this setup, you could have:
repository.save(entity);
which just calls
entity.saveIn(this);
I re-read this and I notice that the entity is still thin because it is simply dispatching its persistence to the repository. But in this case, the entity is supposed to be thin because you didn't describe any other domain logic. In this situation, you could say "screw Double Dispatch, give me accessors."
And yeah, you could, but IMO it exposes too much of how your entity is implemented, and those accessors are distractions from domain logic. I think the only class that should have gets and sets is a class whose name ends in "Accessor".
I'll wrap this up soon. Personally, I don't write my entities with saveIn() methods, because I think even just having a saveIn() method tends to litter the domain object with distractions. I use either the friend class pattern, package-private access, or possibly the Builder pattern.
OK, I'm done. As I said, I've obsessed on this topic quite a bit.

"thin models to service layer objects" is what you do when you really want to write the service layer.
ORM is what you do when you don't want to write the service layer.
When you work with an ORM, you are still aware of the fact that navigation may involve a query, but you don't dwell on it.
Lookup tables can be a relational crutch that gets used when there isn't a very complete object model. Instead of things referencing things, you have codes, which must be looked up. In many cases, the codes devolve to little more than a static pool of strings with database keys. And the relevant methods wind up in odd places in the software.
However, if there is a more complete object model, we have first-class things instead of these degenerate lookup values.
For example, I've got some business transactions which have one of n different "rate plans" -- a kind of pricing model. Right now, the legacy relational database has the rate plan as a lookup table with a code, some pricing numbers, and (sometimes) a description.
[Everyone knows the codes -- the codes are sacred. No one is sure what the proper descriptions should be. But they know the codes.]
But really, a "rate plan" is an object that is associated with a contract; the rate plan has the method that computes the final price. When an app asks the contract for a price, the contract delegates some of the pricing work to the associated rate plan object.
There may have been some database query going on to lookup the rate plan when producing a contract price, but that's incidental to the delegation of responsibility between the two classes.

I aggree with DeadBeef - therein lies the tension. I don't really see though how a domain model is 'anemic' simply because it doesn't save itself.
There has to be much more to it. ie. It's anemic because the service is doing all the business rules and not the domain entity.
Service(IRepository) injected
Save(){
DomainEntity.DoSomething();
Repository.Save(DomainEntity);
}
'Do Something' is the business logic of the domain entity.
**This would be anemic**:
Service(IRepository) injected
Save(){
if(DomainEntity.IsSomething)
DomainEntity.SetItProperty();
Repository.Save(DomainEntity);
}
See the inherit difference ? I do :)

Try the "repository pattern" and "Domain driven design". DDD suggests to define certain entities as Aggregate-roots of other objects. Each Aggregate is encapsulated. The entities are "persistence ignorant". All the persistence-related code is put in a repository object which manages Data-access for the entity. This way you don't have to mix persistence-related code with your business logic. If you are interested in DDD, check out eric evans book.

Related

Downside of having string properties in service contracts that can contain a full json model

We are working with a DDD framework in our company. We are changing a lot of core things in our API because we are still growing and we are still in our enfant phase when designing a good API.
The problem is that there are alot of flows already in the same api. Which are not compatible with eachother.
We have an order service and a product service.
Normally when the product model radically changes, we have a major impact in the order model.
Now im here listing all kind of red flags which should never happen but I simply dont have control over how it needs to be done. That is pretty much management pushing for a fast solution. And leading to bad shortcuts...
The way is has been decided to overcome that Order needs to adapt constantly. They made a property in the orderline called productConfiguration. This is in the contract of the service and is direcrtly translated as is in the DB tables. This contains the product model that can change. In json format.
For me its very clear that this is very dangerous to do this. Because i nthe end you need to change this json into an actual object. So you just move the restrictions from the service contract to code logic. Which makes it worse cause it will only cause an issue at run time...
Are there other major things I just know about, so I can bring it to the table to avoid this way of working...
Using strings that are directly converted into DB tables is not just in your opinion a bad design. It's an opinion shared by a lot of us.
What do you do when an object changes? For example, the new one requires an attribute that the old one didn't had. How do you manage this situation? I suppose that you've to change everything, including the objects stored before. Or build a kind of transformation layer where you translate objects from the old to the new design. A lot of extra work.
Anyway, given that the two domains are separated, what are the information that change so much and require such a design? I mean, for most of the things you could know at the beginning what do you need for your part of the domain. For the rest, I would prefer to have a kind of service that given an Id gives you the information from the other domain. You can change this service (here could be also json obj, if nothing than just showing is required) and adapt to your/their needs. But, it's just a solution that comes from my limited knowledge of your processes.
Other ways are also possible, as long as you can always understand which version of the design are you using.

Populating a Maximo field using a db function: Why is this a bad practice?

In a separate SO question, I asked how to populate a Maximo field using a db function:
Take value from FieldA, send to a db function, and return value to FieldB
A Stack Overflow community member was kind enough to answer the question and provided this advice:
And all that said, you should just use the automation script to do
what you have the database function doing, if at all possible. To be
more blunt, what you are wanting to do is not considered good
practice. So, make sure to include in your script's comments your
justification for not following good practice.
If we assume that there aren't any out-of-the-box methods for doing what I want (Spatial Query), then why would referencing a database function from Maximo be a bad practice?
(Bear in mind that I'm new to the IT industry. I would benefit from layman's terms.)
I can be a little verbose, so I'll apologize up front for that. And it may seem like I'm wandering, but I'll try to bring it back together at the end.
As I said in my answer to your first question, Take value from FieldA, send to db function, return value to FieldB, calling a stored procedure (or stored function or whatever) from an automation script is not "good" practice. That isn't to say, dogmatically, that it shouldn't ever be done, but to say that, as a rule, it should be avoided. When making an exception to the good practice rule is the best way to solve a particular problem, your code should document why you chose (or were forced) to make an exception. And I stand by that answer to your first question, which made no mention of a special circumstance.
If there are no out-of-the-box configuration options for doing what you want, such as crossovers or relationships or domains or etc in Maximo, then your next option should be in-product customization options (also known as "small 'c' customizations), if they exist. It so happens that in the case of Maximo you have "automation scripting" or "autoscripting" in Python or JavaScript, with all (Java) classes in the JVM's / server's classpath at your disposal (possibly including Maximo Spatial's Java class methods), for an in-product customization option. Using examples from Maximo 76 Scripting Features, you can even figure out how to call RESTful APIs, like those exposed by ESRI's ArcGIS, over HTTP or HTTPS.
If in-product (small "c") customizations don't work don't work well enough (such as causing performance problems), then it is generally acceptable, though not supportable, to customize the product itself (aka a big "C" customization). (Generally acceptable, as many companies would accept that rationale for developing a big "C" customization, but not supportable, as the vendor will ask you to remove your Customization and reproduce your problem if a problem is found and if it is at all conceivable that your Customization could be contributing to the problem in any way.) In the case of Maximo, writing your own Java classes or stored procedures are generally considered big "C" customizations.
In the case of Maximo, and you could probably generalize that to any COTS product, updating Maximo data from a stored procedure is considered exceptionally bad practice. This is because such updates are not subjected to Maximo's business rules and logic, which can lead to data integrity problems, support problems, and more. In particular, triggers often assume that Maximo has made database updates in a particular order (parent data being inserted before child data, for example) when its documentation explicitly disclaims commitment to such order. (If it doesn't anymore, it used to.)
All that in mind, if out of the box Maximo doesn't provide a configuration for doing what you need, and if you can't use autoscripting to do what you want, even with access to all of Maximo's and Java's libraries (in that order of preference), then it would be acceptable to use an automation script to call a database function to calculate a value for you to store via Maximo. In fact, in that scenario, calling a function from your script would be far better than having a trigger set the value, because, assuming you update Maximo via it's API, such as mbo.setValue("attribute","value"), your script will still leave the auditing, security, validation, data integrity, and other business rules in operation. As a bonus, any professional Maximo consultants (like me) you bring on to help with projects will waste less time (read: your money) trying to figure out what you are doing and why so they don't break it.
I hope that helps.

Single Responsibility Principle Core Understanding

In brushing up on the SRP I read this document which I located via Uncle Bob's page on principles of OOD. I find the following passage puzzling and somewhat at odds with the rest of the document:
"If, on the other hand, the application is not changing in ways that cause the the two responsibilities to change at different times, then there is no need to separate them. Indeed, separating them would smell of Needless Complexity. There is a corollary here. An axis of change is only an axis of change if the changes actually occur. It is not wise to apply the SRP, or any other principle for that matter, if there is no symptom."
While I understand the answer to many software development questions is "it depends" principles like the SRP appear to be almost universally beneficial and to be implemented as a matter of course. The SRP itself affords code a high adaptability to future changes in requirements. Isn't the point to separate out responsibilities from the get-go to avoid struggling with highly coupled code and cascading changes later on?
I would really appreciate some clarification on this to make sure my understanding of this core principle is correct. Thanks in advance!
From my humble understanding, in the Modem example that is presented here, it might be possible that responsibilities of the modem (Connection and Data Exchange) will change as one.
You have two possibilities here :
When the protocol changes, it is possible that only the connection part change, or only the data exchange part change. It this case you should have two interfaces, because a change of protocol in the data does not imply a change of protocol in the connection.
When the protocol changes, it will always change the connection part and the data exchange part. In that case, you don't need two interfaces, because everytime you will have to rewrite the connection part, you are sure that the data exchange will change as well. In that case, you have two responsibilities put on the same change Axis (which is the protocol handled by the modem), so you can leave them inside a single interface.
The key to this statement is "not changing in ways that cause the two responsibilities to change at different times". Let's say for the sake of argument you have a PaymentLogger and a Payment class. Every time you create a new PaymentType (CreditCard, Cash, Paypal, etc) you need to update the PaymentLogger to log actions specific to those Payments. Instead of splitting out a PaymentLogger class you could have Payment class have a method called Log which does whatever is specific for itself.
In this case it could be that the act of recording actions should be build into the class itself since creating a new Payment requires also creating a new PaymentLogger. It's a responsibility that should have been part of Payment all along.

Should I instantiate a collection or inherit from collection?

I've asked myself this question a number of times when creating classes, particularly those involving collections, but I've never come up with a satisfactory answer. It's a OOP design question.
For example, in a checkbook register program say I have a class of BankAccount. BankAccounts contain data involving the Name of the account, the Type of account (enum of Checking, Saving,...), and other data, but most importantly is a collection of the Adjustments (deposits or withdrawals) in the account.
Here, I have two options for keeping a collection of the Adjustments:
Instantiate a collection and keep it as a member within the BankAccount class. This is like saying "BankAccount has a collection of Adjustments."
Inherit from collection. This is like saying "BankAccount is a collection of Adjustments."
I think both solutions are intuitive, and, of course, both offer some advantages and disadvantages. For example, instantiating allows the class (in languages that allow only a single base class) to inherit from another class, while inheriting from collection makes it easy to control the Add, Remove, and other methods without having to write surrogate methods to 'wrap' those.
So, in such situations, which is a better approach?
To me, a bank account has a collection of adjustments. A bank account is not a collection of adjustments, because it "is" much more than that: it also "is" a name and a type, etc.
So, in your case (and similar cases), I suggest you aggregate a collection inside your class.
In case of doubt, avoid inheritance. :-)
I can argument this further. In order to use inheritance properly, the subclass must satisfy Liskov's substitution principle; this means that, in your case, BankAccount should be a valid type anywhere a Collection is expected. I don't think that's the case, because a Collection probably exposes methods such as Add() and Remove(), whereas you will want to exert some control over adding and removing adjustments from your bank account rather than letting people add and remove them freely.
Personally, I would say BankAccount has a collection of Adjustment. It will probably have other properties that aren't exclusively about what has been deposited or withdrawn ( customer, bank account type, etc ).
In terms of design, my BankAccount object would expose a late-loading property of type Adjustments.
In terms of use within the code, I would instantiate the bank account, and if I needed to know what had gone in and out of the account, I would use the exposed property. The BankAccount would be the primary object, responsible for providing the Adjustments related only to the instantiated account.
Instantiate, definitely.
I agree with the other posters about Bank Account being "more" than just a collection of other items.
Or maybe you jut picked an example which really screams out for "instantiate".
Examples:
What happens if your Bank Account needs a second collection of completely different items? (Example: collection of people who can operate on it, like husband and wife, for example, collection of credit cards, paypal accounts or anything else that can "operate" on your bank account).
Depending on the language a collection exposes too much of its info: if another object needs to access Adjustements... say for displaying your movements history on a web page you automatically expose your "collection" for injection, deletion and so on.
I think getting overly caught up in semantics like "is this more is-a or has-a" is a little bit dangerous - at the end of the day, what matters is how well your design solved the problem, how maintainable it is, etc. In fact, personally, a turning point in the way I understand object oriented programming was letting go of "objects as nouns". Objects are, when you get down to it, an abstraction one level up from a function, nothing more or less.
This was a long way to say "has a". :-) Subclassing is complicated, using is easy.

Business Objects - Containers or functional? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
Where I work, we've gone back and forth on this subject a number of times and are looking for a sanity check. Here's the question: Should Business Objects be data containers (more like DTOs) or should they also contain logic that can perform some functionality on that object.
Example - Take a customer object, it probably contains some common properties (Name, Id, etc), should that customer object also include functions (Save, Calc, etc.)?
One line of reasoning says separate the object from the functionality (single responsibility principal) and put the functionality in a Business Logic layer or object.
The other line of reasoning says, no, if I have a customer object I just want to call Customer.Save and be done with it. Why do I need to know about how to save a customer if I'm consuming the object?
Our last two projects have had the objects separated from the functionality, but the debate has been raised again on a new project. Which makes more sense?
EDIT
These results are very similar to our debates. One vote to one side or another completely changes the direction. Does anyone else want to add their 2 cents?
EDIT
Eventhough the answer sampling is small, it appears that the majority believe that functionality in a business object is acceptable as long as it is simple but persistence is best placed in a separate class/layer. We'll give this a try. Thanks for everyone's input...
Objects are state and behavior together. If an object has sensible behavior (e.g., calculating age for a Person from their birth date, or a total tax for an Invoice), by all means add it. Business objects that are nothing more than DTOs are termed an "anemic domain model." I don't think it's a design requirement.
Persistence is a special kind of behavior. What I'm calling "sensible" is business behavior. A business object need not know that it's persistent. I'd say that a DAO can keep persistence separate from business behavior. I don't put "save" in the "sensible" category.
Business objects CAN have business functionality.
Persistence is not a business functionality , but is technical implementation.
Long story short:
Save/Update/Delete/Find etc - keep away from the business objects in a persistence layer.
CalculateSalary, ApplyDiscount etc are business related methods and can be:
methods of the business objects (so BO is self contained representation of entity) or;
separate services implementing particular functionality (so BOs are acting more like DTOs).
As for the point 2.
I should mention that the approach 2.1 tends to make the BOs too bloated and violate SRP. While 2.2 introduces more maintenance complexity.
I usually balance in between 2.1 and 2.2 so that I put trivial things related to the data into Business Objects and create services for a bit more complex scenarious (if there are more than 4 lines of code - make it a service).
This shifts the paradigm of Business Objects to be more Data Transfer Objects instead.
But this all makes project easier to develop, test and maintain.
The answer is the same regardless of platform or language. The key to this question is whether an object should be able to be autonomous or whether it is better for any given behavior to be spread out among objects with more focused responsibility.
For each class the answer might be different. We end up with a spectrum along which we can place classes based upon the Density of Responsibility.
(Level of responsibility for behavior)
Autonomy - - - - - - - - - - - - - - - - - - - Dependence
High
C - <<GOD object>> <<Spaghetti code>>
l -
a -
s -
s -
-
s -
i -
z -
e - <<Template>> <<Framework>>
low
Let's say you favor letting the class perform all the behaviours itself, or as many as you can. Starting on the left side of this graph, when you make your class more autonomous, the size of the class will grow unless you continuously refactor it to make it more generic. This leads to a template. If no refactoring is done, the temdency is for the class to become more "god-like" because if there is some behavior it needs, it has a method for that. The number of fields and methods grow and soon become both unmanageable and unavoidable. Since the class already does so much, coders would rather add to the monstrosity than try to piece it apart and cut the Gordian knot.
The right side of the graph has classes that depend on other classes to a large degree. If the dependency level is high but the individual class is small, that is a sign of a framework; each class doesn't do much and requires lots of dependent classes to accomplish some function. On the other hand, a highly-dependent class that also has a large amount of code is a sign that the class is full of Spaghetti.
The key to this question is to determine where you feel more comfortable on the graph. In any event, individual classes will end up spread out on the graph unless some organizational principle is applied, which is how you can achieve the results of Template or Framework.
Having just written that, I would say that there is a correlation between class size and degree of organization. Robert C. Martin (or "Uncle Bob") covers similar ground with package dependencies in his very thorough paper on Design Principles and Design Patterns. JDepend is an implementation of the ideas behind the graph on page 26 and complements static analysis tools such as Checkstyle and PMD.
I think it makes more sense for business objects to know how to "handle" themselves, then to have to put that burden elsewhere in the system. In your example, the most logical place to deal with how to "save" customer data would be, to me, in the Customer object.
This may be because I consider the database to be the "data container", so I'm in favor of "business objects" being the higher level that protects the data container from direct access AND enforces standard "business rules" about how that data is accessed/manipulated.
We've used Rocky Lhotka's CSLA framework for years and love the way it is designed. In that framework all of the functionality is contained in the objects. While I can see the value of separting the logic out, I don't think we'll switch away from this philosophy anytime soon.
Business objects should be about encapsulating data and associated behaviors of the business entity modeled by that object. Think of it like this: one of the major tenets of object-oriented programming is encapsulating data and associated behaviors on that data.
Persistence is not a behavior of the modeled object. I find development progresses more smoothly if business objects are persistence ignornant. Developing new code and unit testing new code happen more quickly and more smoother if the business objects are not specifically tied to the underlying plumbing. This is because I can mock those aspects and forget about having to go through hoops to get to the database, etc. My unit tests will execute more quickly (a huge plus if you have thousands of automated tests that run with each build) and I will have less stress because I won't have tests failing because of database connection issues (great if you often work offline or remotely and can't always access your database and oh, by the way, those aspects (database connectivity etc.) should be tested elsewhere!).
The other line of reasoning says, no, if I have a customer object I just want to call Customer.Save and be done with it. Why do I need to know about how to save a customer if I'm consuming the object?
Knowing that Customer has a Save method is already knowing how to save a customer object. You haven't avoided the problem by embedding that logic in your business object. Instead, you've made your code base more tightly coupled and therefore harder to maintain and test. Push off the responsibility of persisting the object to someone else.
The Business objects, as they are named, should obviously coutain their own business logic, the dynamic of the business logic among the domain being in the service layer.
On the other side, could the BO be a data container (DTO?) composition and methods; meaning BO are pure functionnal? That could avoid all the conversions between BO and DTO.
In an MVC architecture,
Can we say that Model contains business objects.