Questions and Answers

Q: Why are we making the random number generator more visible? Isn't object design about encapsulation?
Q: If setting the seed works so well, why make a non-random subclass?
Q:

Why are we making the random number generator more visible? Isn't object design about encapsulation?

A:

Encapsulation isn't the same thing as “information hiding”. For some people, the information hiding concept can be a useful way to begin to learn about encapsulation. However, information hiding is misleading because it is often taken to exremes. In this case, we want to encapsulate the bins of the wheel and the procedure for selecting the winning bin into a single object. However, the exact random-number generator (RNG) is a separate component, allowing us to bind any suitable RNG.

Consider the situation where we are generating random numbers for a cryptographic application. In this case, the built-in random number generator may not be random enough. In this case, we may have a third-party Super-Random-Generator that should replace the built-in generator. We would prefer to minimize the changes required to introduce this new class.

Our initial design has isolated the changes to the Wheel, but required us to change the constructor. Since we are changing the source code for a class, we must to unit test that change. Further, we are also obligated unit test all of the classes that depend on this class. Changing the source for a class deep within the application forces us to endure the consequence of retesting every class that depends on this deeply buried class. This is too much work to simply replace one object with another.

We do, however, have an alternative. We can change the top-level main method, altering the concrete object instances that compose the working application. By making the change at the top of the application, we don't need to change a deeply buried class and unit test all the classes that depend on the changed class. Instead, we are simply choosing among objects with the same superclass or interface.

This is why we feel that constructors should be made very visible using the various design patterns for Factories and Builders. Further, we look at the main method as a kind of master Builder that assembles the objects that comprise the current execution of our application.

See our Why does the Game class run the sequence of steps? Isn't that the responsibility of some “main program? FAQ for more on this subject.

Looking ahead, we will have additional notes on this topic as we add the SevenReds subclass of Player.

Q:

If setting the seed works so well, why make a non-random subclass?

A:

While setting the seed is an excellent method for setting up a unit test, not everyone is comfortable with random number generators. The presence of an arbitrary but predictable sequence of values looks too much like luck for some Quality Assurance (QA) managers. While the algorithms for both Python and Java random number generators are published and well-understood, this isn't always sufficiently clear and convincing for non-mathematicians. It's often seems simpler to build a non-random subclass than to control the existing class.

From another point of view, creating a subclass of a built-in class is a necessary skill. The random number generators are easy classes to extend. Extending the abstract collection classes is also a very useful skill, but somewhat more complex than extending the random number generator.