2

I understand that many design principles conflict with each other in some cases . So, we have to weigh them and see which one is more beneficial. Till now I was aware of SRP principle and did my lot of designs solely based on that but internally I was feeling sometimes wrong while following this principle. Now I came to know about TDA , My feeling got more support with that :)

SRP :- Object should be worried about its own concern not anyone else

TDA :- Behavior (which is dependent only on its object state) should be kept inside the object itself

Example :- I have different Shapes like Rectangle, Square, Circle etc. Now i have to calculate area.

My design till now :- I was following SRP where I had AreaCalculatorService class which will ask state of shape and calculate the area. The reasoning behind this design was shape should not be worried about area calculation as it's not shape responsibility. But ideally i used to think area calc code should reside under each shape as if down the line if new shape comes up I have to modify AreaCalculatorService class(which violates the Open for extension and closed for modification principle(OECM)). But always gave preference to SRP. That seems to be wrong

Myth is broken(At least mine) :- With TDA, looks like my feeling was correct where I should not ask about the state of the object but tell the shape to calculate it's area. Though it will violate the SRP principle but will support OECM principle. As I said design principles conflict with each other some times, but I believe where behavior is completely dependent on its object state, behavior and state should be together.

Another Example :- say I have to calculate the salary of all departments of all Employees in an organization, then we should follow the SRP where SalaryCalculatorService will depend on department and employees.

It will ask the salary of each employee and then do summation on all salaries. So here I am asking for state of employee but still not violating TDA calcSalary is not dependent only on salary of each employee.

Let me know if my interpretation of both these principle is correct or not where I should follow TDA in first case but SRP in second ?

M Sach
  • 33,416
  • 76
  • 221
  • 314
emilly
  • 10,060
  • 33
  • 97
  • 172
  • What are the shapes' responsibilities? It's hard to talk about this things in a vacuum. Your examples are too small. – Javier Nov 05 '16 at 12:32
  • it can be anything which gels logically with shape like `getName()`, keeping it state etc – emilly Nov 05 '16 at 12:34
  • 1
    The area is clearly part of the shapes' interface. How would you even implement that externally in a general way? With lines or curves? There's no SRP violation here and it's definitely TDA. – Javier Nov 05 '16 at 12:37
  • I wanted to analyze the other example but its not sufficiently specified. I don't really understand the problem being analyzed. Why don't you create a real library for a real problem, publish it somewhere and then discuss its design? Or choose an existing library. – Javier Nov 05 '16 at 12:41
  • `There's no SRP violation here and it's definitely TDA..` I believe there is violation of SRP here. In true sense Single Responsibility means there should be single reason to change. Single responsibility of shape is to keep the state of the object nothing else(like area calculation) – emilly Nov 06 '16 at 10:39
  • The area of a shape is a well defined formula so assuming your code the correct formula, you won't have to change the class (except if you change the internal representation of the shape like storing the `radius` instead of the `diameter`). – Phil1970 Dec 15 '16 at 20:38

1 Answers1

5

I think your TDA understanding is correct. The problem is with SRP, in my experience it is the SOLID principle most misunderstood. SRP says that one class should have only one reason to change. The "reason to change" part is often confused with "it should have only one responsibility" so "it must do only one thing". No, it's not like that.
The "reason to change" depends completely from the context of the application where the class resides. Particularly it depends on the actors that interact with the software and that in the future could be able to ask for changes.
The actors could be: the customer who pays for the software, the normal users and some super-users. The DBAs that will manage the database of the application or the IT department that handles the hardware where the application runs. Once you have enumerated all the actors around your software, in order to follow what SRP says, you have to write your class in a way that it has only one single responsibility, therefore only the requests from one actor could require some changes on your class.
So, I think you should follow TDA putting data and behaviors that use those data inside the same object. In this way you can manage the relations among the objects telling them what to do instead of asking data, reducing coupling and reaching a better encapsulation.
SRP as explained above will guide you to decide which behaviors put in one object rather than another one.

Paolo Laurenti
  • 2,714
  • 2
  • 16
  • 18
  • In addition to actors that are persons, you can also consider target applications. For example, you don't want a `Draw` function directly in the shape as it would make it harder to reuse common code if you move to another technology (for ex. Windows, Console, Web, Open GL, Direct X...). – Phil1970 Dec 15 '16 at 20:49