The structure of the Faux Implementation pattern is simple. You want to determine the interface to a real implementation, and you then create one or more implementations that emulate the expected, or known, real implementation. One aspect that the structure cannot capture is the importance of the interface behavior for making a faux implementation work. Figure 14-3 shows the structure of a Faux Implementation pattern. Notice the heavy reliance on the interface and the application's use of the interface over the implementation itself.
The ClassInterface component in Figure 14-3 indicates semantic equivalence and behavioral equivalence. Depending on the environment, the behavioral equivalence may extend beyond what a programmer normally considers in their job. Consider an Atari 2600 game console released in the 1980s. Today's computers dwarf the Atari 2600 game console in terms of processor speeds. A pocket computer, such as a PalmPilot, can emulate the entire hardware console without any difficulties. On the other hand, you do not want to run one of the games from the 1980s at today's processor speeds ”your Pac-Man's hair would fly off. The emulator's behavior must ensure the game plays with the same feel of the 1980s.
Thus, the FauxImplementation instance of the ClassInterface component must behave in the same way as the RealImplementation instance. Consider your own Web Service environment. In the event that you use the Faux Implementation pattern to test your own service implementation with an expected interface to an external Web Service, you could end up with a service that works, but not as expected. Your FauxImplementation instance may run quickly, in milliseconds ; however, when you connect to the RealImplementation instance, you find that it does not return for days. Because you misunderstood the RealImplementation instance's behavior, you could end up redesigning your Client late in the development process.
There are three components to a Faux Implementation pattern. The definitions are what you would expect from object-oriented programming with a stress on behavioral interface in the class interface definition:
ClassInterface: The ClassInterface component defines the application- programming interface to concrete classes as well as the expected behavior for implementations of the interface. If a behavior is not robustly defined, an implementer of the FauxImplementation instance may end up making guesses or assumptions as to the behavior of a RealImplementation instance. Each guess or assumption of the behavior makes the FauxImplementation instance less effective.
RealImplementation: The RealImplementation component is the expected embodiment of the class interface. For example, in a Web Service environment, one would expect Apache Axis to host a Web Service; therefore, it would be the "real" implementation. In the music viewer example, the viewer should expect the RealImplementation component to read music from an input source, as defined in the architecture.
FauxImplementation: The FauxImplementation component is, essentially , a deviation from the expected implementation of the class interface. From the perspective of the class interface and a user of the class, there should be no difference between the FauxImplementation component and the RealImplementation component. Looking under the covers of the FauxImplementation component, a developer finds elements that they do not expect. In the case of hardware emulation, a program on a user interface functions fine, but underneath you have only a piece of software, not a fully functioning phone. The test program is similar; the FauxImplementation component may generate random music scores to test the boundary conditions of the music viewer, but the component does not receive input from files or MIDI input.
The examples in this chapter have shown the Atari 2600 example, which built the RealImplementation component first. At some point, engineers reverse-engineered the ClassInterface component and proceeded to build FauxImplementation components. The test scenario lets the architects build the ClassInterface component, lets the developer of the real implementation's client build the FauxImplementation component, and lets other developers work on the RealImplementation component. You could also get a ClassInterface component, build a FauxImplementation component, and never build a RealImplementation component, as is the case in this chapter's sample.
The class interface dictates the interactions between a client and a faux implementation. Figure 14-4 shows that the client instantiates a faux implementation rather than a real implementation and then calls an operation against it.
Developers use different techniques for instantiating the faux implementation. A developer using the faux implementation for testing will hide the implementation behind a class factory. By using a class factory and allowing it to instantiate the implementation, the factory hides whether the faux implementation or the real implementation is in use. With this technique, a developer can easily switch the real implementation into their code when the real implementation team delivers the component.