Constructing Independent Objects
The theme running through this is that sufficiency is sufficient. When an object has been identified as part of the solution to a problem and contributes to that solution to the extent needed (even if for now that extent is “demonstrate that a solution is viable”), then it is ready to use. There is no need to situate the object in a taxonomy of inherited classes, but if that helps to solve the problem, then by all means do it. There is no need to show that various objects demonstrate a strict subtype relationship and can be used interchangeably, unless solving your problem requires that they be used interchangeably. There is no need for an object to make its data available to the rest of the program, unless the problem can be better solved (or cheaper solved, or some other desirable property) by doing so.
I made quite a big deal earlier of the Open-Closed Principle, and its suggestion that the objects we build be “open to modification.” Doesn’t that mean that anticipating the ways in which a system will change and making it possible for the objects to flex in those ways?
To some extent, yes, and indeed that consideration can be valuable. If your problem is working out how much to bill snooker players for their time on the tables in your local snooker hall, then it is indeed possible that your solution will be used in the same hall on the pool tables, or in a different snooker hall. But which of those will happen first? Will either happen soon? Those are questions to work with the Goal Donor and the Gold Owner—http://wiki.c2.com/?GoldOwner, the person paying for the solution) on answering. Is it worth paying to solve this related problem now, or not?
Regardless of the answer, the fact is that the objects are still ready to go to work as soon as they address the problem you have now. And there are other ways to address related problems anyway, which don’t require “future-proofing” the object designs to anticipate the uses to which they may be put. Perhaps your SnookerTable isn’t open to the extension of representing a pool table too, but the rest of the objects in your solution can send messages to a PoolPlayer in its stead. As the variant on the Open-Closed Principle showed, these other objects could be ignorant of the game played on the table.
Some amount of planning is always helpful, whether or not the plan turns out to be. The goal at every turn should be to understand how we get to what we now want from what we have now, not to already have that which we will probably want sometime. Maybe the easiest thing to do is to start afresh: so, do that.