Lets see both these cases in the following example. Lets assume we have written a two Logger classes that log strings in a file and outputs on screen.
Saturday, May 29, 2010
Adapter Pattern
Lets see both these cases in the following example. Lets assume we have written a two Logger classes that log strings in a file and outputs on screen.
Wednesday, May 26, 2010
The Builder Pattern
Lets see how this is done. First we need to create a abstract class which serves as a parent for the monthly and yearly calendar classes.
AbstractCalendar.java:
{
public abstract void createTopPanel();
public abstract void createBottomPanel();
public abstract void buildCalendar();
public abstract JComponent getCalendar();
Now we create the Monthly and yearly calendars.
MonthlyCalendar.java
{
public void buildCalendar()
{
//put all panels at proper positions
}
@Override
public void createBottomPanel()
{
//create bottom panel
}
@Override
public void createTopPanel()
{
//create top panel
}
}
YearlyCalendar.java
{
public void buildCalendar()
{
//put all panels at proper positions
}
@Override
public void createBottomPanel()
{
//create bottom panel
}
@Override
public void createTopPanel()
{
//create top panel
}
}
Now we have created the concrete classes. It time for us to create the Director. If you remember, the Director is responsible for building the required object. Below is that Director.
public class CalendarBuilder
{
AbstractUICalendar m_calendar;
public CalendarBuilder(AbstractUICalendar calendar)
{
m_calendar = calendar;
}
public JComponent getUI()
{
m_calendar.createTopPanel();
m_calendar.createBottomPanel();
m_calendar.buildCalendar();
return m_calendar.getCalendar();
/*The above returns the complete calendar*/
}
}
public class BuilderMain
{
public static void main(String[] args)
{
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
AbstractUICalendar calendar = null;
String calType = "MONTHLY"; //Hardcoded choice
if(calType.equals("MONTHLY")
{
calendar = new MonthlyCalendar();
}
else
{
calendar = new YearlyCalendar();
}
CalendarBuilder cb = new CalendarBuilder(calendar);
frame.getContentPane().add(cb.getUI());
frame.pack();
frame.setVisible(true);
}
}
In the above example I have hardcoded the choice. But in real time applications, the choice may come from a button or any other parameter.
The result of the above code is given below just for your reference.
Tuesday, May 25, 2010
The Singleton Pattern
How do we make a class return no more than one instance? One way is to make the constructor private. This makes sure no object of this class can be created outside of the class. We then add a static method which creates the object of the class, if it does not exist already, and return it to the caller.
Following code outlines our process:
public class DBConnection
{
private static DBConnection dbConnection;
private DBConnection()
{
/* Create connection here using the various DB parameters*/
}
public static DBConnection getInstance()
{
if(dbConnection == null)
{
dbConnection = new DBConnection();
}
return dbConnection;
}
/*Add other required methods*/
}
Abstract Factory Pattern
The next simpler pattern is the Abstract Factory Pattern. This pattern gives one level of abstraction above the Factory pattern. In the Factory pattern we saw the factory class returns a concrete object. In Abstract Factory Pattern, the abstract factory class returns factories which in turn returns concrete objects for use. The following image might give you the real idea behind this cool pattern.
The following code gives you a simple implementation of the above representation.
InvestmentFactory.java - The Abstract factory class.
public class InvestmentFactory
{
public Investment getInvestment(String risk)
{
if(risk.equals("HIGH"))
{
return new StockFundFactory();
}
else if(risk.equals("LOW"))
{
return new MutualFundFactory();
}
else
{
return new BondFactory();
}
}
}
StockFactory.java - A factory class returned by the abstract factory.
public class StockFactory extends Investment
{
public IUnit getUnit(String type)
{
IUnit stock = null;
if(type.equals("LARGE"))
{
stock = new LargeCompanyStock();
}
else if(type.equals("SMALL"))
{
stock = new SmallCompanyStock();
}
else
{
stock = new MidCompanyStock();
}
return stock;
}
}
MutualFundFactory.java - Another factory class.
public class MutualFundFactory extends Investment
{
public IUnit getUnit(String type)
{
IUnit fund= null;
if(type.equals("LARGE"))
{
fund = new LargeCapFund();
}
else if(type.equals("SMALL"))
{
fund = new SmallCapFund();
}
else
{
fund = MidCapFund();
}
return bond;
}
}
In the caller method we can use the following code snippet to get the desired object we need:
InvestmentFactory af = new InvestmentFactory();
IUnit unit = inv.getUnit("LARGE");
System.out.println(unit.totalAmount());
A more suitable example can be given using the Java swing UI. There is a method UIManager.getSystemLookAndFeelClassName() which will return the name of the class which specifies the underlying platform's UI class(It may be the UI class for Windows, Mac or Linux). This name can act as the parameter which decides the UI object returned by the abstract factory class. The UI object thus returned itself is a factory(objects of type com.sun.java.swing.plaf.windows.WindowsLookAndFeel or com.sun.java.swing.plaf.gtk.GTKLookAndFeel etc..) from which we can get concrete objects like buttons, check boxes, lists etc.. Hope you understand this example if the previous Investment example is not clear enough.
Monday, May 24, 2010
Factory Pattern
The first design pattern we are about to see is the Factory Method pattern. It is a very simple pattern and widely used. In this pattern we use a factory class which produces objects and delivers them to us. The objects created share a common ancestor. The factory class does nothing but create objects based on a condition passed to it as a parameter.
You might have already used this kind of object creation already in some of your programs without knowing it is a factory pattern. In fact, many programmers use design patterns without knowing their official existence. Following is a Java example for the above representation. I am going to use only java and I presume that the reader has a pretty good grasp of the basics of core Java.
ILogger.java. This is the interface which will be the parent of other concrete logger classes.
public interface ILogger
{
public void log(String str);
}
ConsoleLogger.java. This class will put our log strings onto the screen.
public class ConsoleLogger implements ILogger
{
public void log(String str)
{
System.out.println(str);
}
}
FileLogger.java. This class will store the strings into a file. Where and how the file are stored are out of scope for our discussion here because we concentrate only on the pattern.
public class FileLogger implements ILogger
{
private File logFile;
public FileLogger(File logFile)
{
this.logFile = logFile;
}
public void log(String str)
{
/*
* Logic Append the string
* into the log file.
*/
}
}
LoggerFactory.java. This is the factory class which will create the objects for us. Please note that the objects created depends upon the string loggerType that we pass to the method getLogger. The string is just an example. The condition object can be of any Java object, but we rarely come across such a situation.
public class LoggerFactory
{
public static ILogger getLogger(String loggerType)
{
if(loggerType.equals("console"))
{
return new ConsoleLogger();
}
else if(loggerType.equals("file"))
{
File logFile = new File("Log file path");
return new FileLogger(logFile);
}
else
{
// return console logger by default
return new ConsoleLogger();
}
}
}
LoggerMain.java. This file does not appear in the image above, but this may be any class which uses the objects returned by the factory. Please note that errors and exceptions that may occur are not handled in these examples so that it simplifies the code for us to easily understand.
public class LoggerMain
{
public static void main(String[] args)
{
ILogger logger = LoggerFactory.getLogger(args[0]);
/*
* Use the logger to log stuff
*/
}
}
Usage:
The Factory pattern is used in situations where ,
- The class cannot anticipate which object it needs to create until someone tells it to.
- We need to centralize the details of which class is created.
Types of Programming Design Patterns
There are many design patterns that are categorized based on the creation of objects, composition of objects and communication between objects. When we hear the keyword 'types' we tend to think one type can be a replacement for the other(or atleast i think so :-) ). However this is not true. Every type is unique in its own way and suited best for different situations. Okay, Now the design patterns are broadly classified into three types:
The Creational Patterns deal with how the objects are created. These patterns show us different ways of creating objects so that the program does not depend on the way these objects are created. It helps us to delegate the creation task to a class saving us from the hard coded way of creating the objects using the "new" keyword. There are many different Creational patterns. Some of the popular patterns are:
The Factory Pattern in which we have a simple decision making class which creates objects for us depending on some conditional parameter we pass to that class' method.
The Abstract Factory Pattern which is one level above the factory pattern. The abstract factory returns objects which are themselves pure factory objects which in turn gives us the required objects.
The Builder Pattern which creates complex objects step by step.
The Prototype Pattern which creates duplicate objects by cloning.
The popular Singleton Pattern which creates one(and only one) object of a class.
The Structural Patterns represents how classes and objects are combined to form larger structures. Here the class patterns use inheritance to accomplish the their task and Object patterns include other objects within them to accomplish the task. Let see som of the structural patterns:
The Adapter pattern which can be used to link two classes using an Interface.
The Facade Pattern in which a single class can represent an underlying subsytem.
The Proxy Pattern where a class takes the responsibility of a complex class. This can be better understood if one s familiar with the RMI in Java.
The Decorator pattern which can add functionalities to objects dynamically.
The Behavioural Patterns represent the different ways of communication between classes. Some of the behavioral patterns are:
The Chain of Responsibility Pattern in which the command/message is passed through objects until the message is recognized and acted upon.
The Command Pattern in which a command or action gets executed when an event occurs on an object.
The Observer Pattern in which a number of concerned classes are notified of a change in a class.
The State Pattern in which the states that the command passes through are remembered for future action.
The Iterator pattern which provides a way to traverse a list of data in a class.
We will see each of these patterns in detail in the further posts. I am going to use Java as a means of providing examples to better understand these patterns. Ofcourse, the reader can use any language as the examples are extremely simple and provided with rudimentary class diagrams.
Sunday, May 23, 2010
Design Patterns in programming
Welcome! I believe you are one of those guys on the lookout for a simple article about design patterns. If you are a master in design patterns already, you might get bored by this 'Yet another novice article' :)
I was one of the numerous programmers who started coding applications with curiosity right after learning a programming language. There are no words to express the joy one experiences when his code, a work of art, produces the expected results seamlessly. All goes well until someone else(or the developer himself) tries to extend the functionality of the existing program to provide new functionalities. The difficulty arises due to poor readability, poor reuse, strong coupling and finally the developer ends up modifying the code over and over again, sometimes resulting in a time that is not far less than developing the code from the scratch. Ofcourse, I was no exception. So I have decided to write down my understanding of the design patterns so that it gives a basic understanding to someone who starts a journey into the world of design patterns.
Over the years, programmers have faced these woes and refined their programming practices such that the design minimizes coding problems that arise due to less readability, less interoperability and strong coupling between classes (and much more unspeakable horrors....). These practices are captured and documented, which we call today as the design patterns. The design patterns are more apt for Object Oriented Programming languages. The design patterns are discovered on the go. In fact many programmers who have no knowledge of design patterns, are in fact, using them! For example, inheritence itself is a design pattern.
I am going to write simple articles about design patterns which might serve as a starting point to learning design patterns. There are numerous sites out there which teach all the possible design patterns that exist, in detail which you can refer if you need to go to an advanced level(as if you don't know this!!).