23.8. Facade (GoF)

Another requirement chosen for this iteration is pluggable business rules. That is, at predictable points in the scenarios, such as when makeNewSale or enterItem occurs in the Process Sale use case, or when a cashier starts cashing in, different customers who wish to purchase the NextGen POS would like to customize its behavior slightly.

To be more precise, assume that rules are desired that can invalidate an action. For example:

  • Suppose when a new sale is created, it is possible to identify that it will be paid by a gift certificate (this is possible and common). Then, a store may have a rule to only allow one item to be purchased if a gift certificate is used. Consequently, subsequent enterItem operations, after the first, should be invalidated.

  • If the sale is paid by a gift certificate, invalidate all payment types of change due back to the customer except for another gift certificate. For example, if the cashier requested change in the form of cash, or as a credit to the customer's store account, invalidate those requests.

  • Suppose when a new sale is created, it is possible to identify that it is for a charitable donation (from the store to the charity). A store may also have a rule to only allow item entries less than $250 each, and also to only add items to the sale if the currently logged in “cashier” is a manager.

In terms of requirements analysis, the specific scenario points across all use cases (enterItem, chooseCashChange, ...) must be identified. For this exploration, only the enterItem point will be considered, but the same solution applies equally to all points.

Suppose that the software architect wants a design that has low impact on the existing software components. That is, she or he wants to design for a separation of concerns, and factor out this rule handling into a separate concern. Furthermore, suppose that the architect is unsure of the best implementation for this pluggable rule handling, and may want to experiment with different solutions for representing, loading, and evaluating the rules. For example, rules can be implemented with the Strategy pattern, or with free open-source rule interpreters that read and interpret a set of IF-THEN rules, or with commercial, purchased rule interpreters, among other solutions.

To solve this design problem, the Facade pattern can be used.

Facade

Context/Problem

A common, unified interface to a disparate set of implementations or interfaces—such as within a subsystem—is required. There may be undesirable coupling to many things in the subsystem, or the implementation of the subsystem may change. What to do?

Solution

Define a single point of contact to the subsystem—a facade object that wraps the subsystem. This facade object presents a single unified interface and is responsible for collaborating with the subsystem components.


A Facade is a “front-end” object that is the single point of entry for the services of a subsystem;[4] the implementation and other components of the subsystem are private and can't be seen by external components. Facade provides Protected Variations from changes in the implementation of a subsystem.

[4] “Subsystem” is here used in an informal sense to indicate a separate grouping of related components, not exactly as defined in the UML.

For example, we will define a “rule engine” subsystem, whose specific implementation is not yet known. It will be responsible for evaluating a set of rules against an operation (by some hidden implementation), and then indicating if any of the rules invalidated the operation.

The facade object to this subsystem will be called POSRuleEngineFacade. The designer decides to place calls to this facade near the start of the methods that have been defined as the points for pluggable rules, as in this example:

						public class Sale
						{
						public void makeLineItem( ProductSpecification spec, int quantity )
						{
						SalesLineItem sli = new SalesLineItem( spec, quantity );
						// call to the Facade
						if ( POSRuleEngineFacade.getInstance().isInvalid( sli, this ) )
						return;
						lineItems.add( sli );
}

// ...
						} // end of class
					

Note the use of the Singleton pattern. Facades are often accessed via Singleton.

With this design, the complexity and implementation of how rules will be represented and evaluated are hidden in the “rules engine” subsystem, accessed via the POSRuleEngineFacade facade. Observe that the subsystem hidden by the facade object could contain dozens or hundreds of classes of objects, or even a non-object-oriented solution, yet as a client to the subsystem, we see only its one public access point.

And a separation of concerns has been achieved to some degree—all the rule-handling concerns have been delegated to another subsystem.

Summary

The Facade pattern is simple, and widely used. It hides a subsystem behind an object.

Exercise Challenges

Exercise 1:

Design rule handling with the Strategy pattern, whose class names are dynamically discovered by reading from an external source.

Exercise 2:

If implementing in Java, design rule handling with Jess, a free-for-academic-use rule interpreter available at http://herzberg.ca.sandia.gov/jess/


Facades are usually accessed via the Singleton pattern. They provide Protected Variations from the implementation of a subsystem, by adding an Indirection object to help support Low Coupling. External objects are coupled to one point in a subsystem: the facade object.

Related Patterns


As described in the Adapter pattern, an adapter object may be used to wrap access to external systems with varying interfaces. This is a kind of facade, but the emphasis is to provide adaptation to varying interfaces, and thus it is more specifically called an adapter.

UML notation— The UML provides a general purpose grouping notation called a package, which is a kind of tabbed folder icon. Packages can be used to show logical groupings of objects; they may correspond to something like Java packages or C++ namespaces, or to other logically distinct aggregate components or subsystems. Note that in Figure 23.19, only the POSRuleEngineFacade is public with respect to its package.

Figure 23.19. UML package notation.


There is more complex UML notation available to illustrate subsystems, but the notation in Figure 23.19 will suffice for now. Designing with packages is explored in greater detail in the next iteration.

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

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