Session E-PATT

Pattern Implementation in VFP

Steven M. Black
SBC / UP!


Introduction

This is an overview of selected object-oriented design patterns, and how to build them in Visual FoxPro. The patterns exposed here are:

At the outset, the goal of this paper is to introduce implementations of object oriented design patterns to the FoxPro community. Hopefully it will serve to stimulate some productive discussion. Why? Three reasons: Firstly because patterns help us illustrate object usage and programming style. Secondly, understanding the give-and-take among patterns helps to avoid silly tactical mistakes. Third: knowledge of how design patterns work together is a pre-requisite to become an architect — in any field!

Pattern language is a vast topic, and much of it is beyond the scope of this paper. We won’t dwell on many significant aspects of pattern semantics. Suffice here to say that software patterns exist, here are a few of them, and here’s how to rig them in Visual FoxPro.

Want to learn more on object-oriented design patterns? A bibliography, interesting reading, is included near the end of this document. In fact, this paper arises because a common question I hear from colleagues is "These are evocative concepts, but how can I implement these designs in Visual FoxPro?"


Notation

The graphic representations of classes and their interaction is easier if we understand the object-oriented notation for which, unfortunately, there is no common standard. The class and object diagrams herein are in based on omt (Object Modeling Technique) pioneered by Rumbaugh with a few twists, hopefully for clarity.

Figure 1 shows diagrams for abstract and concrete classes. The class name is in bold type at the top of the box. Key operations, suffixed with (), and the names of instance variables, then appear below.

Object relationships are depicted with arrows and lines, as shown in Figure 2, and show the following types of interrelations:

Inheritance is depicted with a large triangle. Here FaxServer and CommPortServer are subclasses of the Output class.

Instantiation is shown with a dashed arrow, here meaning that CreationTool instantiates FaxServer.

‘Part-of’ or aggregation relationships are shown with arrows with diamond bases. Here the OutputManager is composed of, among other things, one or many objects of the Output class.

Referencing is depicted with arrows: The FaxServer keeps one reference to CommPortServer, and OutputManager keeps one (arrowhead) or many (filled circle) objects of the Output class.

Pseudocode examples appear in pseudo-edit windows.


Three Bridge Implementations in Visual FoxPro

Bridge patterns split interfaces from implementations so the two can vary independently. bridge structures are objects composed of interface and implementation sub-objects, and the more flexibly the better. The workings should be direct and simple: the interface object forwards client requests to the appropriate implementation object.

Look for bridge patterns when hiding implementation details, wherever extensibility is required, and always when an object interface and its implementation are separate. The bridge is pattern is independent of scale and found nearly everywhere: encapsulated objects, systems of objects, even entire frameworks can be modeled on bridge.

bridge is fittingly classified as a Structural Pattern. Other common names for bridge are evelope and letter and handle-body. Those descriptive names are good — the dual-object nature of bridge patterns is well conveyed, as is the rather tightly coupled interface usually found between them.

Here we’ll look at three simple ways bridge patterns can be built in FoxPro: First with member properties, second we’ll do more flexible implementations using member arrays, and third using object composition within containers.

One way to build a bridge is as diagrammed in Figure 4. Here an interface member points to an Implementation.

In general terms, here’s how such systems are constructed in VFP. What follows is a simple illustrative class that provides WAIT WINDOW services.

Another example of this sort of bridge is found in Codebook where the cBizobj (business object) class uses an object of the cDataBehavior class to implement the usual table navigation and record-processing functions. The following diagram illustrates this:

Starting from the Member Property bridge, it’s a short stretch to provide multiple simultaneous implementations by using multiple member properties or, as described below, member arrays.

Code sample 1 is modified here to support four different types of dialogs to extend the legacy WAIT WINDOW capability.

Containership bridge implementations are similar to array member bridge implementations except that, in FoxPro, containership management is superbly implemented. The Controls() array, PARENT keyword, SetAll(), and AMEMBERS(,,2) make it easy to manage any depth of containership nesting.

The containership relationship is illustrated below, followed by an illustrative code example.

On balance, classes built as bridges are easier to extend and adapt since their interfaces and implementations can be subclassed independently. Even though interfaces and implementations are decoupled, a high degree of cohesion between participants is to be expected unless steps are taken to abstract their respective interfaces.

The way I see it, a good rule of thumb is: When building a new class, always first consider making it a bridge.


A Chain of Responsibility Pattern in Visual FoxPro

Chain of responsibility patterns decouple a message sender from its receiver by giving many objects a chance to handle the message. The identity of the eventual service-providing object(s) may not be known to the sender, so the chain of responsibiliy routes the request until it is adequately handled.

A good place to find chain of responsibiliy patterns is within easily traversed hierarchies, like containership. With containership the logic is usually simple: "If an object can’t handle a request, then delegate it to its Parent". Help systems, among others, frequently use this pattern to invoke context-sensitive help. Chain of responsibility can be implemented without containership by using object pointer registration schemes.

Here’s a way to structure a chain of responsibility: When in doubt, delegate to THIS.PARENT. In the example below, nested boxes delegate their Click() event upwards until it is handled. Don’t be fooled by all this code, for most of it just sets up the example. The only code you really need is in the Click() methods of the container classes. The code follows, starting on the next page.

In our example we use PARENT referencing to algorithmically reckon the next successor in the chain. There are other ways to do it, including direct referencing, where each object keeps pointers to one or more successors. Assigning objects to these pointers must be managed, of course, and care must be taken to avoid both circularities and unhandled requests.

chain of responsibility can also be built with a handler class that broadcasts the message to a sequence of objects until the message is satisfactorily handled. A variant of this uses object registration mechanisms to maintain the list and sequence of objects to be called.

You may need to pass parameters along the chain. This can be problematic if a variety of classes participate in the successor chain, especially if a handler is involved and the identity of the receiver classes isn’t known for certain. In this case, it’s most helpful to standardize message passing using objects instead of parameters. Like always, a mature and predictable programming interface helps.

Finally, it’s useful to note that a chain of responsibility doesn’t need to end when a message is handled by a receiver in the chain. It may well be desirable for the message to be broadcast to many objects regardless.


Voyeur Patterns in Visual FoxPro

Voyeur patterns invasively observe and react to exposed members without the knowledge or consent of the event participants. Voyeurs decouple the viewed objects by encapsulating part, or all, of the system’s behavior into a controlling object.

A good place to find a voyeur pattern is at the boundary between two incompatible, incomplete, or low-cohesive systems. Voyeur activity is usually triggered by timers, or alternatively from within regularly repeating event loops.

voyeur, like observer (a pattern discussed in Gamma et al.), is a behavioral pattern. It is similar to observer except that subjects are passive — they don’t actively notify their observer — and they don’t need to know any details about the voyeur’s existence.

An good example of a voyeur is Ken Levy’s SuperCls utility. SuperCls is a timer-activated toolbar whose function is to provide class information services while editing class methods. It works as follows: The timer polls WONTOP() and fires the toolbar.Show() and toolbar.Hide() methods as appropriate.

Here’s another example of a voyeur, wherein a timer regularly polls attributes and sets properties accordingly. The key here is note that the subjects themselves have no code germane to the function of the form. In this case, the form reports the position and distance of the mouse relative to its origin. The design surface looks like Figure 8, the source is in Sample6, and an illustration of the finished product is in Figure 9.

As it so happens, using a voyeur for this implementation is cleaner than many other ways of doing it. Alternatives, which typically involve using the various MouseOver() methods to refresh the display, is less practical because:1) we cannot easily control the refresh rate, 2) we need to code many MouseOver() events because visible objects eclipse form's view of the mouse, 3) thus most objects need to "know" about the context of this implementation or, alternatively, know a mediator to accomplish the chore, and 4) rigged as it is, all the code is in a single place — the observer itself.

 

Voyeurs are great for dynamically linking two uncooperating objects. For timer-based voyeurs, expect overhead loading proportionate to their number, firing frequency, code executed and, as usual, the Timer() event will occasionally get in the way when trace is running. Note that, like all things in VFP, timers don’t fire while menu popups are activated.


Two Mediator Patterns in Visual FoxPro

A mediator object, depicted in Figure 11, abstracts inter-workings of two or more objects. They are communication hubs that serve to decouple objects — objects don’t need to know about each other, they just need to know their mediator.

Look for mediator patterns where objects are decoupled and in situations when inter-object behavior variation is present or expected. Mediators well serve situations where complex protocols must be managed, and when centralized access points are desirable.

mediator is a behavioral pattern. Other pattern names sometimes used for mediator are sender-pass through-receiver, and observer. When we speak of mediator, it’s a system of at least three objects messaging in a star topology.

Following are diagrams of two mediator implementations, one from Tazmanian Traders, the other from Y. Alan Griver's Visual FoxPro Codebook. The horizontal splitter control in Tazmanian Traders, which comes from the tsGen class library, contains two shapes and two scrolling command buttons. As the handle shape is moved, or the scroll buttons are clicked, messages are sent to the splitter, which then messages selected items on the form.

In Codebook, toolbar navigation buttons call a business object class (cBizObj) which mediates in a one-way direction between the form (of class cBizObjForm) and the data behavior object (of class cDataBehavior). This simplifies the programming interface — only the cBizObj class protocols need be known — and allows for the easy substitution of the data behavior implementations from the cDatabehavior class. Note that several bridge patterns are evident here separating programming interfaces from implementations.

The study of object oriented patterns is a very new discipline. The best and most complete works have all been published in the past 18 months. If you’d like to read more about object oriented design patterns, consider the following books. This list is sorted in the order I would read them.

Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides. Design Patterns: Elements of Reusable Object-Oriented Software. Reading, MA:Addison-Wesley 1995.

James O. Coplein, Douglas Schmidt. Pattern Languages of Program Design. Reading, MA:Addison-Wesley 1995.

Peter Coad. Object Models: Strategies, Patterns and Applications. Englewood Cliffs, NJ, Yourdon Press 1995.

Wolfgang Pree. Design Patterns for Object-Oriented Software Development. Reading, MA:Addison-Wesley 1994.