I'm struggling to find good ways to split up classes without exposing private data. Most articles I read about SRP seem to ignore how the new classes that take on the separated responsibilities access the data that once used to be private to the original class.
Take, for example, a
Gripper class representing a robotic gripper in a graphical computer simulation. This class handles the logic of a gripper, pickup up items, rotating them, putting them down in a different position, etc. The gripper can also draw itself onto a GUI.
This breaks the SRP, because there are 2 reasons for the
Gripper class to change: Changes to the logic as to how a gripper operates, and changes as to how a gripper is drawn. However,
Gripper has some private data members that are used by both the logic and the drawing portion. Simply exposing those members trough some (const) getters feels like a step backwards. I'd be exposing implementation details, tying myself down to supporting this new "interface" and it seems downright wrong.
So I came up with this:
/* Takes the data needed to draw a gripper and does so. */
DrawGripper(const Foo& foo, const Qux& qux);
/* Additional methods to draw other things. */
Draw(Renderer& renderer) const
- Better separation of responsibilities. Apart from the
Drawfunction, consisting of 1 line of code, all the drawing code is now gone from
Renderercould be a abstract interface, easily allowing different implementations.
- Data can be passed by const reference to
DrawGripperwhereas a plain memberfunction would have total access to all members.
Gripperstill has a
Drawfunction and knows about
I feel the con is manageable tough. In the end, one of the reasons for
Gripper to exist is to eventually be drawn onto the screen, so the fact that it still has a
Draw function does not seem too bad. Perhaps this is a case of having to choose the lesser of 2 evils? The alternative of exposing private data being far worse imho.
Am I on the right track here? Is this a good system that can be deployed in cases like this? Any problems or better ways?