BCA
BCA

Reputation: 8506

The Single Responsibility Principle and Entity Classes

Regarding the Single Responsibility Principle, and the ubiquitous warnings regarding too-large classes, how does all this apply to entity classes? Aren't entities, by their very nature, supposed to encapsulate everything about an entity that goes together? Is that not their "single responsibility"?

Otherwise, suppose your entity class is getting “too big” as some might say, how would you actually break this up without breaking the natural encapsulation that that entity should provide? If you have a Person class, with just a name, age and favorite food, then obviously they should all be properties of Person. But what if you needed to add 20 more similar properties, like eye color, isRightHanded, ReligionOfChoice, etc? Just because there are many of them, does that all the sudden mean they need to be split up into different classes? This seems silly to have a separate class for “Properties1To5” and “Properties6To10” and then compose the Person classes with these?

Or is it more correct to keep even 100 properties (which theoretically could be unrelated to each other except for the fact that they belong to a Person) directly inside the Person class, since the single responsibility of the Person class is to encapsulate everything about a person?

Upvotes: 2

Views: 474

Answers (1)

Moo-Juice
Moo-Juice

Reputation: 38825

If you look at some coding-standard documents, you may have come across the "Classes should be no larger than 'x' methods" argument. These "standards" exist in good faith but don't have much use. The idea was to stop developers creating 8000 line, monolithic, one-size-fits-all classes. I know, I've seen it before and it's horrendous. However, limiting the "number of methods per class", or in your example, "the number of propeties per POCO", can obfuscate things.

Indeed, taking the example of "No more than 30 methods per class" (Like, what?), you end up with fragmented classes which are fragmented purely because of the 30-method limit. This actually makes things worse.

classes should be as big as they need to be. And this really comes down to the design and requirements of your application. What do I really need to know about a person, and what matters within the realms of my requirements? If I need 100 attributes, and the rules of the business has a defacto need to record each and every one of those attributes - and they are used in reporting and/or business logic, then it makes sense that your Person has 100 attributes. Splitting them up in to blocks just confuses the data, confuses the code, and makes things a bit of a nightmare.

That said, there are times when you might want to split certain traits out in to other classes that are related to our master Person POCO. You mention religion as an attribute, and perhaps in a business application it is necessary. But if the point of your application is to figure out how people change their religion over time, it makes no sense for it to be part of the Person does it? We suddenly now have a ReligionInstance POCO which records their belief at a particular point in time. I'm sure you can see where I am going with this, as out of those other 100 attributes I am sure - depending on the needs of a project - others may be segregated out in to their own objects because that's what the logic needs. For example, it would easy to add the 7/8 fields required for an address. Sounds good, nice and easy. However, if the person moves we have no record of where they were previously. Suddenly Addresses look like a good candidate to move in to their own object and link back to the person if we care that they moved.

When you mention composing, I kind of think in the same way - because there are going to be objects that you want to create that are composites of other information. If we imagine that we store a Person and we also store 1 or more Address POCOs.. depending on the business logic, I might just want the person, or I might want them and their addresses.

This is what I call compositing. Our database has our Person and our Address, and we have a non-database POCO called PersonWithAddresses (for example) which will give us the person's information and all their addresses. The business rules define these objects and I consider PersonWithAddresses to be a composite.

Now here's the thing, what repository deals with this? we might have a PersonRepository and an AddressRepository, both taking responsibility for their individual POCOs. Might we also have a CompositePerson repository that uses both of these repositories to construct a more heavyweight POCO that has all the information we need? We are keeping with the Single Responsibility pattern. We're keeping things lightweight when we need to, and nothing is doing anything more than it should.

Upvotes: 2

Related Questions