Thinking in Patterns: Step 2a

I will work through the patterns, selecting them based on how each pattern creates the context for the other patterns.

When determining which patterns create the context for others in my problem domain, I apply an easy technique: I look through all possible pairings of the patterns, taken two at a time. In this case, there are six possible pairings, as shown in Figure 12-2.

Figure 12-2. Different possible relationships between the patterns.


If you have several other patterns, it may look like this process could get very involved. That turns out not to be the case. With a little experience, many of the patterns can easily be eliminated up front from contention for the primary pattern. Usually, you have to deal with only a handful or so.

In this case, there are few enough combinations that we can look at all of the possibilities.

What exactly do we mean when we say one pattern creates the context for another? One definition of context is the interrelated conditions in which something exists or occurs—an environment, a setting.

In the courtyard example in Chapter 11, “How Do Experts Design?” Alexander said that a porch exists in the context of the courtyard. The courtyard defines the environment or the settings in which the porch exists.

A pattern in a system often relates to other patterns in the system by providing a context for these other patterns. In your analysis, it is always valuable to look for whether and how a pattern relates to the other patterns, to look for the contexts that the pattern creates or provides for the other patterns as well as those contexts in which the pattern itself exists. You may not be able to find these every time. But, by looking, you will create higher-quality solutions.

Looking for context is an essential tool to add to your bag of analysis and design tools.

A rule to use when considering context.

During one of my projects, I was reflecting on my design approaches. I noticed something that I did consistently, almost unconsciously: I never worried about how I was going to instantiate my objects until I knew what I wanted my objects to be. My chief concern was with relationships between objects as if they already existed. I assumed that I would be able to construct the objects that fit in these relationships when the time comes to do so.

The reason I do this is that I need to minimize the number of things that I have to keep in my head during a design. Usually I can do so with a minimal amount of risk when I delay thinking about how to instantiate objects that meet my requirements. Worrying too early is counterproductive; it is better not to worry about instantiating objects until I know what it is that I need to instantiate. I will let tomorrow take care of itself—at least when it comes to instantiation!

Perhaps this seems sensible to you. I had never heard it stated as a rule and I wanted to check it out before adopting it as universal. I trust my intuition as a designer, but I am certainly not foolproof. So, I have conferred with several other experienced developers on this subject; without exception, they also follow this rule. That gives me confidence to offer it to you:

Rule: Consider what you need to have in your system before you concern yourself with how to create it.

This fits Alexander's context rule: When you have a design pattern that involves creating objects, the objects set the context for the pattern.


When I am considering which pattern creates context for the others, I begin with Abstract Factory. The Abstract Factory's context is determined by the objects it needs to instantiate, as shown by the following:

  • There will be a set of make methods, the implementation of each having a return new xxx in it.

  • At this time, I do not know what xxx will be.

  • xxx will be determined by the objects I am using.

  • The objects that I will need to use are defined by other patterns.

Since I cannot even define the Abstract Factory until I know the classes the other patterns will define, it is not the seniormost pattern (the pattern that creates the context for the other patterns). Therefore, I reject it for now as the pattern to start working on.

In fact, the Abstract Factory will be the last pattern I do (unless another creational pattern shows up during my initial design, in which case, both creational patterns will vie for being last).

Seniormost patterns constrain the other patterns.

Seniormost is my term for the one or two patterns that establish a context for the other patterns in my system. This is the pattern that constrains what the other patterns can do. Other terms you could use are outermost patterns or context-setting patterns.


There are three pairs of patterns left to consider:

  • Adapter–Bridge

  • Bridge–Facade

  • Facade–Adapter

As someone new to patterns, I may not see any pattern that is obviously dependent on another pattern, nor any pattern that sets the context for all others.

When there is not an obvious choice, I have to work through the combination of patterns systematically looking for the following:

  • Does one pattern define how the other pattern behaves?

  • Do two patterns mutually influence each other?

The Adapter pattern is about modifying the interface of a class into another interface that the client is expecting. In this case, the interface that needs adapting is the OOGFeature. The Bridge pattern is about separating multiple concrete examples of an abstraction from their implementation. In this case, the abstraction is Feature and the implementations are the V1 and V2 systems. It sounds like the Bridge will need the Adapter to modify OOGFeature's interface, that is, the Bridge will use the Adapter.

Clearly there is some relationship between Bridge and Adapter.

Can I define one of the patterns without another, or is one of the patterns needed by another?

Looking at the patterns tells us what to do.

  • I can talk about the Bridge pattern as separating the Features from the V1 and V2 systems without actually knowing how I will use the V1 and V2 systems.

  • However, I cannot talk about using an Adapter pattern to modify the V2 system's interface without knowing what it will be modified into. Without the Bridge pattern, this interface doesn't exist. The Adapter pattern exists to modify the V2 system's interface to the implementation interface the Bridge pattern defines.

Thus, the Bridge pattern creates the context for the Adapter pattern. I can eliminate the Adapter pattern as a candidate for seniormost pattern.

The relationship between context and used by.

Often, it seems that when one pattern uses another pattern, the pattern that is used is within the context of the pattern doing the using. There are likely exceptions to this rule, but it seems to hold most of the time.


Now I only have to compare Bridge–Facade and Facade–Adapter.

I will look at the Bridge and Facade relationship first because if the Bridge turns out to be the primary pattern there as well, I do not need to consider the Adapter–Facade relationship (remember, I am only trying to identify the seniormost pattern at this point).

It should be readily apparent that the same logic that applied to Bridge and Adapter also applies to Bridge and Facade:

  • I will be using the Facade pattern to simplify the V1 system's interface.

  • But what will be using the new interface I create? One of the implementations of the Bridge pattern.

Therefore, the Bridge pattern creates the context for the Facade. The Bridge is the seniormost pattern.

According to Alexander, I am supposed to start with the whole. Going back to the beginning, I find that I do not yet have the context for the Bridge.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.89.82