Behavioral patterns are those which are concerned with interactions between the objects. The interactions between the objects should be such that they are talking to each other and still are loosely coupled. The loose coupling is the key to n-tier architectures. In this, the implementation and the client should be loosely coupled in order to avoid hard-coding and dependencies.
The behavioral patterns are:
Patterns.
1. Chain Of Responsibility Pattern
2. Command Pattern
3. Interpreter Pattern
4. Iterator Pattern
5. Mediator Pattern
6. Momento Pattern
7. Observer Pattern
8. State Pattern
9. Strategy Pattern
10. Template Pattern
11. Visitor Pattern
I will describe each one of these in details
Friday, April 30, 2010
Proxy Pattern
Structural Patterns - Proxy Pattern
The proxy pattern is used when you need to represent a complex with a simpler one. If creation of object is expensive, its creation can be postponed till the very need arises and till then, a simple object can represent it. This simple object is called the “Proxy” for the complex object
The cases can be innumerable why we can use the proxy. Let’s take a scenario. Say, we want to attach an image with the email. Now, suppose this email has to be sent to 1 lakh consumers in a campaign. Attaching the image and sending along with the email will be a very heavy operation. What we can do instead is, send the image as a link to one of the sevlet. The place holder of the image will be sent. Once the email reaches the consumer, the image place holder will call the servlet and load the image at run time straight from the server.
Let’s try and understand this pattern with the help of a non-software example as we have tried to do throughout this article.
Let’ say we need to withdraw money to make some purchase. The way we will do it is, go to an ATM and get the money, or purchase straight with a cheque. In old days when ATMs and cheques were not available, what used to be the way??? Well, get your passbook, go to bank, get withdrawal form there, stand in a queue and withdraw money. Then go to the shop where you want to make the purchase. In this way, we can say that ATM or cheque in modern times act as proxies to the Bank.
Let’s look at the code now.
Bank will define the entire method described above. There are references of classes like You (as the person who wants to withdraw money), also Account, as persons account. These are dummy classes and can be considered of fulfilling the responsibilities as described.
Bank.java
Also, the second class is ATMProxy. This also defines the way the transaction can be handled for withdrawal of money.
ATMProxy.java
Here, we can also create another proxy called ChequeProxy. I am not creating it here as the message I wanted to send across has been conveyed with the help of one proxy only. We can see here that creation of object of Bank is very costly, effort and time wise, and so, we can as well use a proxy called ATM to get the result. ATM can internally communicate with the Bank object. So, ATM here is also acting like a façade.
This might and might not happen. It can happen that we at a later stage have to create the same heavy object. We just want to postpone the creation of object to the last minute so that the application is not loaded by resources utilized for creating the object.
The proxy pattern is used when you need to represent a complex with a simpler one. If creation of object is expensive, its creation can be postponed till the very need arises and till then, a simple object can represent it. This simple object is called the “Proxy” for the complex object
The cases can be innumerable why we can use the proxy. Let’s take a scenario. Say, we want to attach an image with the email. Now, suppose this email has to be sent to 1 lakh consumers in a campaign. Attaching the image and sending along with the email will be a very heavy operation. What we can do instead is, send the image as a link to one of the sevlet. The place holder of the image will be sent. Once the email reaches the consumer, the image place holder will call the servlet and load the image at run time straight from the server.
Let’s try and understand this pattern with the help of a non-software example as we have tried to do throughout this article.
Let’ say we need to withdraw money to make some purchase. The way we will do it is, go to an ATM and get the money, or purchase straight with a cheque. In old days when ATMs and cheques were not available, what used to be the way??? Well, get your passbook, go to bank, get withdrawal form there, stand in a queue and withdraw money. Then go to the shop where you want to make the purchase. In this way, we can say that ATM or cheque in modern times act as proxies to the Bank.
Let’s look at the code now.
Bank will define the entire method described above. There are references of classes like You (as the person who wants to withdraw money), also Account, as persons account. These are dummy classes and can be considered of fulfilling the responsibilities as described.
Bank.java
| package structural.proxy; /** * Bank.java * The class acts as the main object for which * the proxy has to be created. As described, going * to bank for withdrawal is very costly time wise. */ public class Bank { | ||
| private int numberInQueue; /** * Method getMoneyForPurchase * This method is responsible for the entire banking * operation described in the write-up */ public double getMoneyForPurchase(double amountNeeded) { // get object for person You you = new You("Prashant"); // get obj for account Account account = new Account(); // get person's account number String accountNumber = you.getAccountNumber(); // passbook got. boolean gotPassbook = you.getPassbook(); // get number in queue int number = getNumberInQueue(); // the number will decrease every few mins while (number != 0) { number--; } // now when the number = 0, check if balance is sufficient boolean isBalanceSufficient = account.checkBalance(accountNumber, amountNeeded); if(isBalanceSufficient) return amountNeeded; else return 0; } /** * returns the number in the queue */ private int getNumberInQueue() { return numberInQueue; } | ||
| }// End of class | ||
ATMProxy.java
| package structural.proxy; public class ATMProxy { | ||
| /** * Method getMoneyForPurchase * This method is responsible for the entire banking * operation described in the write-up */ public double getMoneyForPurchase(double amountNeeded) { // get obj of You to get card You you = new You("Prashant"); // get obj for account Account account = new Account(); boolean isBalanceAvailable = false; // if card there, go ahead if(you.getCard()) { isBalanceAvailable = account.checkBalance(you.getAccountNumber(), amountNeeded); } if(isBalanceAvailable) return amountNeeded; else return 0; } | ||
| }// End of class | ||
This might and might not happen. It can happen that we at a later stage have to create the same heavy object. We just want to postpone the creation of object to the last minute so that the application is not loaded by resources utilized for creating the object.
Flyweight Pattern
Structural Patterns - Flyweight Pattern
The pattern here states about a mechanism by which you can avoid creating a large number of object instances to represent the entire system.
To decide if some part of your program is a candidate for using Flyweights, consider whether it is possible to remove some data from the class and make it extrinsic. If this makes it possible to reduce greatly the number of different class instances your program needs to maintain, this might be a case where Flyweights will help.
The typical example you can see on this in every book will be of folders. The folder with name of each of the company employee on it, so, the attributes of class Folder are: ‘Selected’ , ‘Not Selected’ and the third one is ‘employeeName’. With this methodology, we will have to create 2000 folder class instances for each of the employees. This can be costly, so we can create just two class instances with attributes ‘selected’ and ‘not selected’ and set the employee’s name by a method like:
setNameOnFolder(String name);
This way, the instances of class folder will be shared and you will not have to create multiple instances for each employee.
I was going through this pattern and was trying to find the best suited non-software example. Then, I remembered the talks I had with one of my cousin’s who used to work in a grinding wheel manufacturing company. I am a Chemical Engineer and so, remember the names of chemical compounds. He was telling me that the grinding wheels are used for metal cutting across the industry. Basically the main ingredients for these grinding wheels are Aluminum Oxide (Al2O3) and Silicon Carbide (SiC). These compounds are used in form of grains. For those who remember Chemistry from schools, and for others, just follow the example.
His company manufactures nearly 25000 types of grinding wheels. Now, there is another technicality in this and that is bonding.
There are two types of bondings used to bond the material i.e. Aluminum Oxide and Silicon Carbide together. One is Glass bonding – this is like, the wheel is heated to 1300 degree C and the silicon turns into glass to hold the two materials together. The second type of bonding is Resin bonding, this is when some resins help in holding the materials together. The wheels are in different sizes, have different ratio of materials mixed and have any of these two types of bondings. This decides the strength of the wheel. In all, creating 25,000 types of combinations is a pretty complex looking scenario.
If we consider this from software point of view, we can see that each wheel is of a different type and so, we need to make 25000 classes for taking care of each of the wheel. This of course will be very resource intensive. So, how to avoid this?
Well, we already know a few things and we can see a common pattern in each of the wheels. The common things are as follows:
1. Materials of use – They are always Aluminum Oxide and Silicon Carbide.
2. Each wheel has a bonding.
3. Each wheel has a size.
We can follow one thing, the combination above mentioned three ingredients can give us a large number of instances so, why not take a scenario where only one of these is used in the constructor and rest be passed as method parameters.
Let’s have a look at the code. For every flyweight, there is a factory providing the object instance. Now, naturally wheels are made in a factory so, there is GrindingWheelFactory class which returns the type of wheel needed.
GrindingWheelFactory.java
This class is very important. Let’s have a closer look at the class. It returns a wheel based only on the bonding. As we know that bondings are only of two types, and so, at any point in time, there will be two instances which are negligible as compared to 25000.
The other important class here is of course GrindingWheel. This gets constructed depending on the parameters passed to the method getWheel() of class GrindingWheelFactory. Let’s have a look at the class GrindingWheel.
GrindingWheel.java
This class can have other methods getters and setters for diameter, and ratioAlumina, on which the complete wheel is dependent.
In each of the instances of the wheels, we can pass the values of ratio of alumina to silicon carbide as method parameters and also the sizes which can lead to a great number of combinations.
Hence, we can see that by using the flyweight pattern, we can reduce the instances of the class.
The pattern here states about a mechanism by which you can avoid creating a large number of object instances to represent the entire system.
To decide if some part of your program is a candidate for using Flyweights, consider whether it is possible to remove some data from the class and make it extrinsic. If this makes it possible to reduce greatly the number of different class instances your program needs to maintain, this might be a case where Flyweights will help.
The typical example you can see on this in every book will be of folders. The folder with name of each of the company employee on it, so, the attributes of class Folder are: ‘Selected’ , ‘Not Selected’ and the third one is ‘employeeName’. With this methodology, we will have to create 2000 folder class instances for each of the employees. This can be costly, so we can create just two class instances with attributes ‘selected’ and ‘not selected’ and set the employee’s name by a method like:
setNameOnFolder(String name);
This way, the instances of class folder will be shared and you will not have to create multiple instances for each employee.
I was going through this pattern and was trying to find the best suited non-software example. Then, I remembered the talks I had with one of my cousin’s who used to work in a grinding wheel manufacturing company. I am a Chemical Engineer and so, remember the names of chemical compounds. He was telling me that the grinding wheels are used for metal cutting across the industry. Basically the main ingredients for these grinding wheels are Aluminum Oxide (Al2O3) and Silicon Carbide (SiC). These compounds are used in form of grains. For those who remember Chemistry from schools, and for others, just follow the example.
His company manufactures nearly 25000 types of grinding wheels. Now, there is another technicality in this and that is bonding.
There are two types of bondings used to bond the material i.e. Aluminum Oxide and Silicon Carbide together. One is Glass bonding – this is like, the wheel is heated to 1300 degree C and the silicon turns into glass to hold the two materials together. The second type of bonding is Resin bonding, this is when some resins help in holding the materials together. The wheels are in different sizes, have different ratio of materials mixed and have any of these two types of bondings. This decides the strength of the wheel. In all, creating 25,000 types of combinations is a pretty complex looking scenario.
If we consider this from software point of view, we can see that each wheel is of a different type and so, we need to make 25000 classes for taking care of each of the wheel. This of course will be very resource intensive. So, how to avoid this?
Well, we already know a few things and we can see a common pattern in each of the wheels. The common things are as follows:
1. Materials of use – They are always Aluminum Oxide and Silicon Carbide.
2. Each wheel has a bonding.
3. Each wheel has a size.
We can follow one thing, the combination above mentioned three ingredients can give us a large number of instances so, why not take a scenario where only one of these is used in the constructor and rest be passed as method parameters.
Let’s have a look at the code. For every flyweight, there is a factory providing the object instance. Now, naturally wheels are made in a factory so, there is GrindingWheelFactory class which returns the type of wheel needed.
GrindingWheelFactory.java
| package structural.flyweight; /** * This factory of wheel is accessed by the client. Everytime, * the client wants a wheel, the software is accessed through this * Factory class. The specifications are passed through the * method parameters and a new wheel is returned. * * User: prashant.satarkar * Date: Apr 8, 2004 * Time: 5:06:13 PM */ public class GrindingWheelFactory { | ||
| /** * The method takes the input parameters and return the appropriate * wheel. * * @return An instance of grinding wheel */ public GrindingWheel getWheel(boolean isGlassBonded) { return new GrindingWheel(isGlassBonded); } | ||
| }// End of interface | ||
The other important class here is of course GrindingWheel. This gets constructed depending on the parameters passed to the method getWheel() of class GrindingWheelFactory. Let’s have a look at the class GrindingWheel.
GrindingWheel.java
| package structural.flyweight; /** * The wheel is formed for different ratio of alumina * and silicon carbide, for a different bonding and for * a different size, which depends on the diameter of * the wheel. * * User: prashant.satarkar * Date: Apr 8, 2004 * Time: 5:13:23 PM */ public class GrindingWheel { | ||
| private int ratioAlumina; private int diameter; private boolean isGlassBonded; /** * Default Constructor * */ public GrindingWheel(boolean isGlassBonded) { this. isGlassBonded = isGlassBonded; } . . . . | ||
| }// End of class | ||
In each of the instances of the wheels, we can pass the values of ratio of alumina to silicon carbide as method parameters and also the sizes which can lead to a great number of combinations.
Hence, we can see that by using the flyweight pattern, we can reduce the instances of the class.
Facade Pattern
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
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
Now let’s consider the facade StoreKeeper.
StoreKeeper.java
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
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
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.
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 | ||
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 | ||
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 | ||
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 | ||
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 | ||
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.
Thursday, April 29, 2010
Decorator Pattern
Structural Patterns - Decorator Pattern
The decorator pattern helps to add behavior or responsibilities to an object. This is also called “Wrapper”. Suppose we have some 6 objects and 2 of them need a special behavior, we can do this with the help of a decorator.
Java Design Patterns suggest that Decorators should be abstract classes and the concrete implementation should be derived from them.
The decorator pattern can be use wherever there is a need to add some functionality to the object or group of objects. Let’s take an example of a Christmas tree. There is a need to decorate a Christmas tree. Now we have many branches which need to be decorated in different ways.
Let’s have a look at the basic Decorator class.
Decorator.java
This class has just one method place(). This method places different types of items on the branches of the tree.
The class ChristmasTree is very simple and has just one method which returns a branch.
ChristmasTree.java
Now we can decorate the branches in three different ways, one is by putting coloured balls on them, by putting coloured ruffles on them and also by putting stars on them.
Let’s have a look at the implementation of these three different types of decorators.
BallDecorator.java
Similarly, we can make StarDecorator and RufflesDecorator. Now, we will see how to use the decorator. Its simple, we just are needed to pass the instance of ChristmasTree class to a decorator.
StarDecorator decorator = new StarDecorator(new ChristmasTree());
This way the decorator will be instantiated and a branch of the Christmas tree will be decorated.
This is a very abstract example and could not be implemented in terms of code fully. But, then, as I have said, I want you to understand the patterns rather than giving you concrete examples. Once the pattern is internalized, you can think of some good software examples yourself.
Decorators, Composites and Adapters
The decorator and adapter patterns are similar. Adapters also seem to decorate the classes. The intent of using adapter is to convert the interface of one or more classes to suit the interface of the client program. In case of decorator, the intent is to add behavior and functionality to some of the objects, not all the objects or adding different functionalities to each of the objects.
In case of composite objects, the client program treats the objects similarly, whether it is a simple or complex object (nodes).
The decorator pattern provides functionality to objects in a more flexible way rather than inheriting from them.
There is however disadvantage of using decorator. The disadvantage is that the code maintenance can be a problem as it provides the system with a lot of similar looking small objects (each decorator).
The decorator pattern helps to add behavior or responsibilities to an object. This is also called “Wrapper”. Suppose we have some 6 objects and 2 of them need a special behavior, we can do this with the help of a decorator.
Java Design Patterns suggest that Decorators should be abstract classes and the concrete implementation should be derived from them.
The decorator pattern can be use wherever there is a need to add some functionality to the object or group of objects. Let’s take an example of a Christmas tree. There is a need to decorate a Christmas tree. Now we have many branches which need to be decorated in different ways.
Let’s have a look at the basic Decorator class.
Decorator.java
| package structural.decorator; public abstract class Decorator { | ||
| /* * The method places each decorative item * on the tree. */ public abstract void place(Branch branch); | ||
| }// End of class | ||
The class ChristmasTree is very simple and has just one method which returns a branch.
ChristmasTree.java
| package structural.decorator; public class ChristmasTree { | ||
| private Branch branch; public Branch getBranch() { return branch; } | ||
| }// End of class | ||
Let’s have a look at the implementation of these three different types of decorators.
BallDecorator.java
| package structural.decorator; /** * Decorates the branch of the tree with * coloured balls. */ public class BallDecorator extends Decorator { | ||
| // Default Constructor public BallDecorator(ChristmasTree tree) { Branch branch = tree.getBranch(); place(branch); } /* * The method places each decorative item * on the tree. */ public void place(Branch branch) { branch.put("ball"); } | ||
| }// End of class | ||
StarDecorator decorator = new StarDecorator(new ChristmasTree());
This way the decorator will be instantiated and a branch of the Christmas tree will be decorated.
This is a very abstract example and could not be implemented in terms of code fully. But, then, as I have said, I want you to understand the patterns rather than giving you concrete examples. Once the pattern is internalized, you can think of some good software examples yourself.
Decorators, Composites and Adapters
The decorator and adapter patterns are similar. Adapters also seem to decorate the classes. The intent of using adapter is to convert the interface of one or more classes to suit the interface of the client program. In case of decorator, the intent is to add behavior and functionality to some of the objects, not all the objects or adding different functionalities to each of the objects.
In case of composite objects, the client program treats the objects similarly, whether it is a simple or complex object (nodes).
The decorator pattern provides functionality to objects in a more flexible way rather than inheriting from them.
There is however disadvantage of using decorator. The disadvantage is that the code maintenance can be a problem as it provides the system with a lot of similar looking small objects (each decorator).
Composite Pattern
Structural Patterns - Composite Pattern
In developing applications, we come across components which are individual objects and also can be collection of objects. Composite pattern can represent both the conditions. In this pattern, you can develop tree structures for representing part-whole hierarchies.
The most common example in this pattern is of a company’s employee hierarchy. We here will also take the same example.
The employees of a company are at various positions. Now, say in a hierarchy, the manager has subordinates; also the Project Leader has subordinates, i.e. employees reporting to him/her. The developer has no subordinates.
So, let’s have a look at the class Employee: This is a simple class with getters and setters for attributes as name, salary and subordinates.
Employee.java
Next we, fill up the tree. You can make a class to access the class Employee and try filling up the tree like this:
Once we have filled the tree up, now we can get the tree for any employee and find out whether that employee has subordinates with the following condition.
Vector subOrdinates = emp.getSubordinates();
if (subOrdinates.size() != 0)
getTree(subOrdinates);
else
System.out.println("No Subordinates for the Employee: "+emp.getName());
Thus the Composite pattern allows you to create a tree like structure for simple and complex objects so they appear the same to the client.
In developing applications, we come across components which are individual objects and also can be collection of objects. Composite pattern can represent both the conditions. In this pattern, you can develop tree structures for representing part-whole hierarchies.
The most common example in this pattern is of a company’s employee hierarchy. We here will also take the same example.
The employees of a company are at various positions. Now, say in a hierarchy, the manager has subordinates; also the Project Leader has subordinates, i.e. employees reporting to him/her. The developer has no subordinates.
So, let’s have a look at the class Employee: This is a simple class with getters and setters for attributes as name, salary and subordinates.
Employee.java
| package structural.composite; import java.util.Vector; public class Employee { | ||
| private String name; private double salary; private Vector subordinates; public Vector getSubordinates() { return subordinates; } public void setSubordinates(Vector subordinates) { this.subordinates = subordinates; } // constructor public Employee(String name, double sal) { setName(name); setSalary(sal); subordinates = new Vector(); } public String getName() { return name; } public void setName(String name) { this.name = name; } public double getSalary() { return salary; } public void setSalary(double salary) { this.salary = salary; } public void add(Employee e) { subordinates.addElement(e); } public void remove(Employee e) { subordinates.remove(e); } | ||
| }// End of interface | ||
/** * This will add employess to the tree. The boss, is PM * and has subordinates. */ | ||
| private void addEmployeesToTree() { CFO = new Employee("CFO", 30000); Employee headFinance1 = new Employee("Head Finance. North Zone", 20000); Employee headFinance2 = new Employee("Head Finance. West Zone", 22000); Employee accountant1 = new Employee("Accountant1", 10000); Employee accountant2 = new Employee("Accountant2", 9000); Employee accountant3 = new Employee("Accountant3", 11000); Employee accountant4 = new Employee("Accountant4", 12000); CFO.add(headFinance1); CFO.add(headFinance2); headFinance1.add(accountant1); headFinance1.add(accountant4); headFinance2.add(accountant2); headFinance2.add(accountant3); | ||
| }// End of class | ||
Once we have filled the tree up, now we can get the tree for any employee and find out whether that employee has subordinates with the following condition.
Vector subOrdinates = emp.getSubordinates();
if (subOrdinates.size() != 0)
getTree(subOrdinates);
else
System.out.println("No Subordinates for the Employee: "+emp.getName());
Thus the Composite pattern allows you to create a tree like structure for simple and complex objects so they appear the same to the client.
Bridge Pattern
Structural Patterns - Bridge Pattern
The Bridge Pattern is used to separate out the interface from its implementation. Doing this gives the flexibility so that both can vary independently.
The best example for this is like the electric equipments you have at home and their switches. For e.g., the switch of the fan. The switch is the interface and the actual implementation is the Running of the fan once its switched-on. Still, both the switch and the fan are independent of each other. Another switch can be plugged in for the fan and this switch can be connected to light bulb.
Let’s see how we can convert this into a software program. Switch is the interface having two functions, switchOn() and switchOff().
Here is the sample code for Switch.
Switch.java
This switch can be implemented by various devices in house, as Fan, Light Bulb etc. Here is the sample code for that.
Fan.java
And implementation as Bulb.
Bulb.java
Here, we can see, that the interface Switch can be implemented in different ways. Here, we can easily use Switch as an interface as it has only two functions, on and off. But, there may arise a case where some other function be added to it, like change() (change the switch). In this case, the interface will change and so, the implementations will also changed, for such cases, you should use the Switch as abstract class. This decision should be made earlier to implementation whether the interface should be interface or abstract class.
The Bridge Pattern is used to separate out the interface from its implementation. Doing this gives the flexibility so that both can vary independently.
The best example for this is like the electric equipments you have at home and their switches. For e.g., the switch of the fan. The switch is the interface and the actual implementation is the Running of the fan once its switched-on. Still, both the switch and the fan are independent of each other. Another switch can be plugged in for the fan and this switch can be connected to light bulb.
Let’s see how we can convert this into a software program. Switch is the interface having two functions, switchOn() and switchOff().
Here is the sample code for Switch.
Switch.java
| package structural.bridge; /** * Just two methods. on and off. */ public interface Switch { | ||
| // Two positions of switch. public void switchOn(); public void switchOff(); | ||
| }// End of interface | ||
Fan.java
| package structural.bridge; /** * Implement the switch for Fan */ public class Fan implements Switch { | ||
| // Two positions of switch. public void switchOn() { System.out.println("FAN Switched ON"); } public void switchOff() { System.out.println("FAN Switched OFF"); } | ||
| }// End of class | ||
And implementation as Bulb.
Bulb.java
| package structural.bridge; /** * Implement the switch for Fan */ public class Bulb implements Switch { | ||
| // Two positions of switch. public void switchOn() { System.out.println("BULB Switched ON"); } public void switchOff() { System.out.println("BULB Switched OFF"); } | ||
| }// End of class | ||
Here, we can see, that the interface Switch can be implemented in different ways. Here, we can easily use Switch as an interface as it has only two functions, on and off. But, there may arise a case where some other function be added to it, like change() (change the switch). In this case, the interface will change and so, the implementations will also changed, for such cases, you should use the Switch as abstract class. This decision should be made earlier to implementation whether the interface should be interface or abstract class.
Subscribe to:
Posts (Atom)
