Reputation: 37
I often get confused about the "reason to change" or "an axis of change" stated in the book.
I have a class that makes a character grab a physics object with its hands.
The grabbable object itself is another class that knows how to get these "grab points" so the grabber class knows where to put the character's hands.
I think this looks right since each class has distinct responsibilities.
But they are so coupled that it almost makes sense for them to be one class only. Would that break SRP since now the class scans for grab points and also moves/attaches the hands of the character to the object, while still being used cohesively?
Upvotes: 0
Views: 115
Reputation: 38094
It is really hard to say whether the classes can be merged into one, however, for the first glance, it looks like you have two responsibilities such as:
So I would stick with two classes. Because if we stick with just one class, then this class will have two reasons to be changed, debugged or edited. So, as a result it will be easier to write unit tests later for your if your classes will be smaller and just have one goal.
Upvotes: 0
Reputation: 59144
The SRP does not tell you to divide classes when they do more than "one thing". That's ambiguous, anyway, since programs are functional hierarchies -- all the "things" that programs do are groups of smaller things.
The SRP tells you to divide classes when they have more than one line of responsibility, like a worker with two bosses. That causes problems, because one boss' instructions might be at odds with what the other boss wants.
In your case, it makes sense that you would want a class that handles the grabbing action. This is the class that you modify when you want to change how grabbing works -- that's its responsibility.
It also makes sense that you should have a class for each kind/type of object, and that class should determine the object's grab points, along with all the other attributes of the object like its shape. This is the class that you modify when you want to change the object(s) -- that's its responsibility.
Do you need a separate scanning class that scans the object definition for grab points? Probably not. I would normally expect the object class to have a method that returns its grab points. Following the other SOLID principles, there should probably be a separate Grabbable
interface that the object class must implement in order to be grabbable, and this interface would define the method that returns grab points.
So hopefully you understand what SRP means now, but bear in mind that there is no best way to divide up your program and determine these lines of responsibility. Deciding how to do this in a way that best meets all of your functional and organizational requirements is mostly what software design is, and it isn't easy.
In particular, if you are making a game, then investigate the Entity, Component, System pattern. This is a very popular way to structure game implementations that is likely to produce a completely different decomposition from what you had in mind.
Upvotes: 0