Facade

advertisement
Design Patterns
Facade
SE516
Melisa Tyira
A design pattern describes a solution to a design problem that can be used over
and over again. The key to the goal of a design pattern is the reuse of objects in order to
avoid rework. The use of existing objects is a major factor towards software
productivity.
A design pattern is described using the following elements: pattern name,
problem, solution, and consequences. A pattern name is given to each design pattern in
order to increase our vocabulary thus being able to discuss design patterns freely without
having to give a description each time. The problem is a description of the design
problem, which also leads to a description of when to apply the pattern. The solution is
not a description of a specific design that will solve the problem but a description of the
elements and interactions between these elements that make up the design. The
consequences are the positive and negative results of applying a design pattern. It is
beneficial to decide the pros and cons of applying a design pattern in order to determine if
there are truly benefits to applying a design pattern.
There are many documented design patterns and groups of these design patterns
are related in some way to one another. These groups of design patterns are: creational
patterns, structural patterns, and behavioral patterns. I will discuss the Facade pattern
which is classified as a structural pattern. Structural patterns are patterns that describe
how classes and objects are structured within a larger structure. Structural patterns can
either be structural class patterns or structural object patterns. Structural class patterns
are concerned with inheritance in order to create interfaces or implementations.
Structural object patterns are concerned with the composition of objects in order to create
new functionality. Facade is an object structural pattern.
2
Facade is used to create common interfaces that interact with a subsystem of
interfaces. This is used because it is less complex and easier for us than having multiple
interfaces interact with a subsystem. A general template for a facade pattern is as
follows:
Client Classes
FACADE
Subsystem
Classes
The client classes access the Facade class, which accesses the subclasses. The Facade
class minimizes the access to subsystem classes that the client classes are not concerned
with. Otherwise, without the Facade class the client classes would access subsystem
classes as shown in the following diagram:
3
Client Classes
Subsystem
Classes
The facade pattern is ideal to use when a simple interface is needed for a complex
subsystem. The larger the subsystem gets, the more classes that are involved, which
makes this easier to reuse and customize. This can also pose a problem by making it
harder for clients that do not wish to customize the subsystem. If customization is
needed, the facade should probably not be used. The facade is also used to reduce the
coupling between the clients and subsystems, therefore, the subsystem is independent of
the client classes and other subsystems. A facade pattern can also be used if there are
multiple subsystems. Multiple facades can be created as an entry point into each
subsystem. If two subsystems are dependent on one another, they can communicate
through a facade.
4
A real-world example that explains the use of a facade is an ordering system. I
have displayed the use of a facade between the client class and subclasses. A client runs
a request that communicates with the facade class to delegate requests to the appropriate
subsystem objects. In this case, order, inventory, and product are the subsystem classes.
Client
request_run
Facade
purchase()
return()
getorderstatus()
checkinventory()
Orders
Inventory
getorder()
num productsinventory()
Product
rem ove()
add()
This same design, not including the facade class would look like the following:
5
Client
purchase()
return()
getorderstatus()
checkinventory()
request_run()
Orders
Inventory
getorder()
num productsinventory()
Product
rem ove()
add()
In this diagram, the client is responsible to determine which class is needed through the
interface. The facade object allows for the client class to access the orders, inventory,
and product subsystem classes by going through a common interface that determines for
the client, which class is needed. This helps in solving the design problem because it is
less complex for the client due to the fact that there are fewer interfaces for the client to
deal with, thus reducing coupling.
In a more general sense, the facade is like a 9-1-1 operator. A client calls the 9-11 operator and the call is directed to the ambulance, hospital, police, etc. The clients are
shielded from these departments and do not have direct access to them. The client uses
the 9-1-1 operator to access these departments and the 9-1-1 operator will dispatch
services as needed. This promotes weak coupling because in the event of a burglary, the
fire department does not need to be contacted. This is how the facade design pattern
works.
Each design pattern has similarities to other existing patterns and can sometimes
be used in place of each other or along with other patterns. The abstract factory pattern
6
can be used in place of, or along with the facade pattern. It can be used to provide an
interface to creating classes in the subsystem or can be used to hide classes that are
specific to a particular pattern. The mediator pattern is also similar to the facade pattern.
The mediator pattern is used to encapsulate common behavior between classes. The
mediator is responsible for controlling interactions between these objects thus reducing
coupling and dependencies. This is similar to the facade pattern except for the fact that
facade does not define new functionality and the subsystem classes do not know about
the facade class like they do in the mediator pattern.
There are many benefits to using the facade design pattern. It allows clients to
deal with less subsystem objects because requests are sent through the facade object and
forwarded to the appropriate subsystem object. Clients do not have to access the
subsystem objects directly. Weak coupling is promoted and dependencies are eliminated
because there is no interaction between the client objects and the subsystem objects.
7
Code Example:
Classes
BackEndOne
BackEndTwo
Broker
Client
Interface
Backend
/**
* Creation date: (09/24/2002 8:50:54 AM)
* @author: Melisa
*/
interface BackEnd {
/**
* Insert the method's description here.
* Creation date: (09/24/2002 8:52:04 AM)
* @return java.lang.String
*/
String login();
}
/**
* Creation date: (09/24/2002 8:45:17 AM)
* @author: Melisa
*/
class BackEndOne implements BackEnd {
/**
* Creation date: (09/24/2002 8:48:21 AM)
*/
public BackEndOne()
{
}
/**
* Creation date: (09/24/2002 8:50:33 AM)
* @return java.lang.String
*/
public String login() {
return "backendone";
}
}
8
/**
* Creation date: (09/24/2002 8:45:43 AM)
* @author: Melisa
*/
class BackEndTwo implements BackEnd {
/**
* Creation date: (09/24/2002 8:48:10 AM)
*/
public BackEndTwo() {}
/**
* Creation date: (09/24/2002 8:49:54 AM)
* @return java.lang.String
*/
public String login() {
return "backendtwo";
}
}
/**
* Creation date: (09/24/2002 8:39:33 AM)
* @author: Melisa
*/
class Broker implements BackEnd{
public static final String BACKENDONE="BACKENDONE";
public static final String BACKENDTWO="BACKENDTWO";
private BackEnd localBackEnd=null;
/**
* Creation date: (09/24/2002 8:40:06 AM)
* @param backEndComponent java.lang.String
*/
public Broker(String backEndComponent) throws Exception
{
if(backEndComponent.equals(BACKENDONE))
{localBackEnd=new BackEndOne();}
else if(backEndComponent.equals(BACKENDTWO))
{localBackEnd=new BackEndTwo();}
else
{throw new Exception("comp not found");}
}
/**
* Creation date: (09/24/2002 8:49:09 AM)
* @return java.lang.String
*/
public String login() {
return localBackEnd.login();
}
}
9
/**
* Creation date: (09/24/2002 8:38:16 AM)
* @author: Melisa
*/
class Client {
/**
* Creation date: (09/24/2002 8:38:38 AM)
*/
public Client() {}
/**
* Creation date: (09/24/2002 8:38:49 AM)
* @param args java.lang.String[]
*/
public static void main(String[] args)
{
try{
Broker broker=new Broker(Broker.BACKENDONE);
System.out.println(broker.login());
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
This is an example of code that does not run but it will explain the use of a facade design
pattern. The client class calls the broker class, which is the facade class. The broker
class determines whether or not the client should access backendone or backendtwo. The
client class is unaware of the methods of the facade class but still receives the output that
was requested.
10
References
Gamma, Erich & Helm, Richard & Johnson, Ralph & Vlissides, Design Patterns:
Elements of Reusable Object-Oriented Design
http://www.agcs.com/supportv2/techpapers/patterns/papers/tutnotes
http://www.agcs.com/supportv2/techpapers/patterns/papers/patexamples.htm
http://www.csc.calpoly.edu/~dbutler/tutorials/winter96/patterns/tutorial.html
11
Download