Remember how we talked about "separation of concerns" and "information hiding", way back in
Step 0?
Well, it seems
we've failed to adhere to these principles in the previous step, by forcing
Eliza.Initialize() to have to know about the internals of the three patterns
(BECAUSE, YES and NO) it uses.
/// <summary< /// Initializes this instance. /// </summary> private void Initialize() { // Initialize the list of patterns that Eliza understands this._patterns = new ListEliza.Initialize() (which is the consumer of patterns) shouldn't have to know what's inside a BECAUSE pattern. It should simply be able to construct one and use it. Real-world example Imagine that in order to replace a burned-out lightbulb you had to:
/// <summary< /// Initializes this instance. /// </summary> private void Initialize() { // Initialize the list of patterns that Eliza understands this._patterns = new List Hiding the complexity of the BECAUSE patternIn order to shield the user from the complexity of the BECAUSE pattern, we'll hide its internals in a BecausePattern class. Since BecausePattern is nothing but a Pattern, we'll make BecausePattern derive from (i.e. be a subclass of) the parent Pattern class. Pattern will contain code that's common to all patterns, while BecausePattern will contain code that's specific to the BECAUSE pattern. Common stuff belongs to the base ("parent") class, while specific stuff belongs to the derived ("child") class. The collection of parent and child classes is called a "class hierarchy", because some classes derive (i.e. descend) from others. For now, let's start with this class hierarchy:Pattern BecausePattern YesPattern NoPatternPattern is the base (parent) class, and BecausePattern, YesPattern and NoPattern are child classes that all derive from Pattern. What's common and what's specific?In our class hierarchy, all three patterns are alike in their behavior, in that:
What can we hide and what can't we hide?Properties and methods that MUST be accessible to users of the class can't be hidden. Everything else can (and should) be hidden. It's that simple! (And you thought computer science was hard? ) Take a closer look at the public properties and methods of the Pattern class and for each, ask yourself if each can be private or does it have to remain public? At the end of this step, compare your answer with the solution.Refining the Pattern and BecausePattern classesNow we're going to do what software engineers do to earn their money. We're going to use our brains and refine (i.e. improve) the Pattern and BecausePattern classes. Our goal is to allow Eliza to construct the BecausePattern class by simply doing:BecausePattern bp = new BecausePattern();
COMING UP WITH A WELL DESIGNED CLASS HIERARCHY IS THE HARDEST (AND PERHAPS MOST REWARDING)
PART OF SOFTWARE ENGINEERING. EVENTUALLY, YOU'LL COME TO RECOGNIZE PATTERNS (no pun intended)
IN HOW CLASSES INTERACT WITH EACH OTHER, AND CREATING A WELL THOUGHT OUT DESIGN WILL COME
NATURALLY TO YOU.
BUT WHEN YOU'RE STARTING OUT, IT CAN FEEL A BIT LIKE TRYING TO FIND YOUR WAY OUT OF A MAZE WITH A BLANKET OVER YOUR HEAD. When you're doneAfter you've modified the Pattern class and created the BecausePattern class:
|