JAVA
DESIGN PATTERNS
Structural
Patterns - Facade Pattern
Facade as the name suggests means the face of
the building. The people walking past the road
can only see this glass face of the building.
They do not know anything about it, the wiring,
the pipes and other complexities. The face hides
all the complexities of the building and displays
a friendly face.
This
is how facade pattern is used. It hides the
complexities of the system and provides an interface
to the client from where the client can access
the system. In Java, the interface JDBC can
be called a facade. We as users or clients create
connection using the “java.sql.Connection” interface,
the implementation of which we are not concerned
about. The implementation is left to the vendor
of driver.
Let’s
try and understand the facade pattern better
using a simple example. Let’s consider a store.
This store has a store keeper. In the storage,
there are a lot of things stored e.g. packing
material, raw material and finished goods.
You, as client want access to different goods.
You do not know where the different materials
are stored. You just have access to store keeper
who knows his store well. Whatever you want,
you tell the store keeper and he takes it out
of store and hands it over to you on showing
him the credentials. Here, the store keeper
acts as the facade, as he hides the complexities
of the system Store.
Let us see how the Store example works.
Store.java
package
structural.facade;
public interface Store
{
|
|
public Goods getGoods(); |
}//
End of interface |
The store can very well be an interface. This
only returns Goods. The goods are of three types
as discussed earlier in this document. RawMaterialGoods,
FinishedGoods and PackagingMaterialsGoods. All
these classes can implement the Goods interface.
Similarly,
the stores are of three types and can implement
the Store interface. Let’s have a look at the
code for one of the stores.
FinishedGoodsStore.java
package
structural.facade;
public class FinishedGoodsStore
implements Store {
|
|
public Goods getGoods() {
FinishedGoods finishedGoods = new FinishedGoods();
return finishedGoods;
} |
}//
End of class |
Now
let’s consider the facade StoreKeeper.
StoreKeeper.java
package
structural.facade;
public class StoreKeeper
{
|
|
/**
* The raw materials are asked for and
* are returned
*
* @return raw materials
*/
public RawMaterialGoods getRawMaterialGoods()
{
RawMaterialStore store = new RawMaterialStore();
RawMaterialGoods rawMaterialGoods = (RawMaterialGoods)store.getGoods();
return rawMaterialGoods;
}
/**
* The packaging materials are asked for
and
* are returned
*
* @return packaging materials
*/
public PackingMaterialGoods getPackingMaterialGoods()
{
PackingMaterialStore store = new PackingMaterialStore();
PackingMaterialGoods packingMaterialGoods
= (PackingMaterialGoods)store.getGoods();
return packingMaterialGoods;
}
/**
* The finished goods are asked for and
* are returned
*
* @return finished goods
*/
public FinishedGoods getFinishedGoods()
{
FinishedGoodsStore store = new FinishedGoodsStore();
FinishedGoods finishedGoods = (FinishedGoods)store.getGoods();
return finishedGoods;
}
|
}//
End of class |
This
is clear that the complex implementation will
be done by StoreKeeper himself. The client will
just access the StoreKeeper and ask for either
finished goods, packaging material or raw material.
How
will the client program access this façade?
Here is a simple code.
Client.java
package
structural.facade;
public class Client {
|
|
/**
* to get raw materials
*/
public static void main(String[] args) {
StoreKeeper keeper = new StoreKeeper();
RawMaterialGoods rawMaterialGoods = keeper.getRawMaterialGoods();
} |
}//
End of class |
In
this way the implementation is left to the façade.
The client is given just one interface and can
access only that. This hides all the complexities.
There
is another way of implementing this. We can
have just one method in our StoreKeeper class
getGoods(String goodsType).
Another
version of StoreKeeper method is here.
StoreKeeper.java
package
structural.facade;
public class StoreKeeper
{
|
|
/**
* The common method
*
* @return Goods
*/
public Goods getGoods(String goodsType)
{
if (goodsType.equals("Packaging"))
{
PackingMaterialStore store = new PackingMaterialStore();
PackingMaterialGoods packingMaterialGoods
= (PackingMaterialGoods)store.getGoods();
return packingMaterialGoods;
}
else if (goodsType.equals("Finished"))
{
FinishedGoodsStore store = new FinishedGoodsStore();
FinishedGoods finishedGoods = (FinishedGoods)store.getGoods();
return finishedGoods;
}
else {
RawMaterialStore store = new RawMaterialStore();
RawMaterialGoods rawMaterialGoods = (RawMaterialGoods)store.getGoods();
return rawMaterialGoods;
}
|
}//
End of class |
The
client program can now create an object of StoreKeeper
class and call method getGoods() passing as
parameter the type of goods required. This can
be done as follows.
new
StoreKeeper().getGoods(“RawMaterials”);
In
this case, the type-casting ill be needed on
client side to narrow down Goods to RawMaterialsGoods.
All
in all, the Façade pattern hides the
complexities of system from the client and provides
a simpler interface. Looking from other side,
the facade also provides the implementation
to be changed without affecting the client code.
|