0

This question already has an answer here:

Assume you have a class. It can really be any class that defines a domain concept like an employee, a product on an e-commerce site, or a car. One of those examples that are oldies but goodies. According to the SRP, that object should be responsible all of "its" things.

I would consider an employee taking a lunch, a product going on sale, or a car accelerating all examples of things that "belong" to those examples. This can include other categorical areas of concern such as affecting the database, firing an event, or changing a simulation while the source object is still responsible for the overall outcome.

The struggle I see there is you either have very flat architectures where an object can (potentially) touch anything or you have rather verbose layers of abstraction that the objects can reasonably rely on. However, the latter feels more like giving up responsibility the more layers there are between a thing and what it's trying to do.

I really don't know where I stand on this, personally. I'd quite likely compromise by splitting the baby, as it were, in most of those scenarios which feels some kind of wrong no matter what I do. Being the middle of 2015, has there been any development toward these kinds of problems that give good guides on where one should be?

I understand the composition over inheritance advice in object construction but when you're formulating ideas and not building objects yet, is there a clear "good" way to go about this?

Edit: So, with the potential duplication of Is SRP (Single Responsibility Principle) objective?, I don't think that's the case. I'm not implying it is or even should be objective. I'm curious if there have been improvements in schools of thought around this subject. I get it's subjective. To illustrate: I don't think anyone would say writing software has one, objectively correct method, but SOLID is often given as a guide to write "good" software. Similarly, given SOLID, where is the thought-space around the SRP and object ownership?

marked as duplicate by JacquesB, Doc Brown, Telastyn, Ixrec, user22815 Aug 1 '15 at 1:23

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • you misunderstand SRP - it doesn't mean that class is responsible for all of it's things. Quite the opposite. SRP means any given module is responsible for one and only one thing, not a collection of things. – Jimmy Hoffa Jul 31 '15 at 18:39
  • So pretty much all the built-in .Net types violate the SRP except for object, for example? The string class alone has a collection of things it does that changes strings. Or, do you mean to say the "one thing" can exist at different abstraction levels (i.e. a class to "manage strings" vs. one to concat two strings)? In that case, how am I misunderstanding the SRP? – Bigsby Jul 31 '15 at 18:52
  • SRP means a class should have one reason to change. You don't want the accounting rules code to change because you changed the database or the UI or the network stack or the authentication or the logging... It involves some element of predicting what kinds of changes there will be, so there is uncertainty and subjectivity involved. – psr Jul 31 '15 at 19:39
1

tl;dr Your decisions on how much to abstract should be dependent upon your business problem to choose how much of the baby to split.

Understanding relationships and how to define them properly without creating 'god' objects is a common problem when architecting solutions. Your idea on compromise is spot on when you are trying to accomplish something and the problem then becomes, what, when, and why do I compromise. First you need to get a good feel for defining relationships properly, SOLID design as it were.

For example, you stated an employee "owns" his lunch break, a product "owns" its sale, and a car "owns" its acceleration, but are these accurate for your business problem. An employee might need to request that he can take his lunch break from a BreakManagement system, while a product might get told its on sale from a CampaignMarketing system, or a Car might accelerate the wheels, but not its acceleration relative to the ground without the help of the a Traction calculation. Really, you need to be able to see the purpose of the system you are trying to build and what entities are required and the relationships between those entities.

Its easy to see that an employee might need to rely on a break management system and that dependency for a system for managing employees, but that might be an invalid relationship for a system that simply keeps track of an employee's hours.

0

I think we've learned a lot since SRP was introduced, but in a more indirect and general way due to the changes in the way software development projects are managed. SRP is a principle that wasn't intended to have a set of strict rules that could be blindly applied to all situations. It depends. There are some general rules that experience has taught us that code written with SRP in mind, tends to be easier to work with. Anything can be taken too far. Programming life would be so much easier if we just put every method in it's own class every single time no matter what. Bad idea.

The notion that if SOLID principles are applied correctly, then two different developers would probably solve the same problem the same way, detracts from the purpose-more robust code. I think they'll be very close, but there should never be an expectation of being a perfect match. What should happen, is an average developer should be able to look at both solutions that applied the SOLID principles "correctly" and be able to understand what the code is doing to the extent that she can alter and extend it as needed.

I would also argue that if two developers worked with the same user/client, for the same length of time, going through all the iterations and steps in an identical project, they would probably end up with similar designs. We not only would expect a novice developer to fail to produce a similar application as a senior developer, but we would be able to tell the difference very easily. We also would know which one is easier to work with - isn't that what it's all about?

It's the requirements that should drive the level of complexity and abstraction and not solely based on a given developer's application of the SOLID principles. If I build a car driving simulator and base acceleration purely on the specs/averages provided by some car rating service that uses identical conditions to do their testing, I wouldn't need a lot of abstractions for this functionality. However, if my simulator's requirements need to involve changing road conditions, elevation, weather conditions and possibly wear and tear on the tires, most developers would suggest not putting all this code in the Car class. If you did and decided to have different types of cars, tracks, seasons, etc., they would see it as a big mess that has now violated SRP. Not because of how they individually build things, but mainly because of the change in requirements.

  • And all this applies to OOP, YAGNI, TDD, DDD, and EIEIO. ;) – JeffO Jul 31 '15 at 18:55
  • I agree with your simulation example where you have a score that you can make certain assumptions on. In the latter, wouldn't tire wear be a property on a Tire object which is a property on the Car object? I don't think a reasonably experienced programmer would say that weather conditions would exist on the Car object itself nor would the road conditions be on the Car. Those are things that don't describe the Car or the Car itself would care about. It would be informed of side affects it needed via Tell Don't Ask. I know it's an example. I'm just trying to follow your train of thought. – Bigsby Jul 31 '15 at 19:11
  • No, that wouldn't surprise me. What would surprise me if weather conditions were baked in the implementation of a Car. It being passed as an argument or something else, imo, would be fine. – Bigsby Jul 31 '15 at 19:38
  • My feeling is to make programming complex when the requirements are complex. Creating a website that is merely a skin for a database (one form = one table) doesn't need 50 layers. – JeffO Jul 31 '15 at 19:45

Not the answer you're looking for? Browse other questions tagged or ask your own question.