Design pattern is a general term that represents reusable solutions with best practices used by object-oriented developers for different types of problems. It defines the concept of template of solving a problem that can be used by many different situations that help to define the system architecture
In 1994, four authors - Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides published a book named "Design Patterns - Elements of Reusable Object-Oriented Software" that introduced the concept of Design Pattern in Software development. These authors are collectively known as Gang of Four (GOF). According to them design patterns are primarily based on following principles of object orientated design
- Program to an interface not an implementation
- Favor object composition over inheritance
Since old object oriented programming, there are mainly three categories of design patterns which are further divided into sub-types based on their functions and characteristics. The three main categories of design patterns are:
- Creational Design Patterns
- Structural Design Patterns and
- Behavioral Design Patterns
There is another category of design pattern specifically concerned with the presentation tier, identified by Sun Java Center is called
- J2EE design patterns
- Creational Design Patterns
- Structural Design Patterns and
- Behavioral Design Patterns
There is another category of design pattern specifically concerned with the presentation tier, identified by Sun Java Center is called
- J2EE design patterns
Design Patterns based on main categories are as follows:
Different design patterns are described below with brief descriptions and simple examples
| 1. Creational Design Patterns |
|
| 2. Structural Design Patterns |
|
| 3. Behavioral Design Patterns |
|
| 4. J2EE Design Patterns |
|
1. Creational Design Pattern
These
design patterns provide a way to create objects while hiding the
creation logic, rather than instantiating objects directly using new
operator. This gives program more flexibility in deciding which objects
need to be created for a given use case.
1.1. Factory Pattern: Creates an instance of several derived classes
Step 1: Create an interface.
Shape.java
Square.java
FactoryPatternDemo.java
Shape.java
public interface Shape {
void draw();
}
Step 2:
Create concrete classes implementing the same interface.
Square.java
public class Square implements Shape {
@Override
public void draw() {
System.out.println("Inside Square::draw() method.");
}
}
Circle.java
public class Circle implements Shape {
@Override
public void draw() {
System.out.println("Inside Circle::draw() method.");
}
}
Step 3
Create a Factory to generate object of concrete class based on given information.
ShapeFactory.java
public class ShapeFactory {
//use getShape method to get object of type shape
public Shape getShape(String shapeType) {
if(shapeType == null){
return null;
}
if(shapeType.equalsIgnoreCase("CIRCLE")) {
return new Circle();
} else if(shapeType.equalsIgnoreCase("SQUARE")) {
return new Square();
}
return null;
}
}
Step 4
Use the Factory to get object of concrete class by passing an information such as type.
FactoryPatternDemo.java
public class FactoryPatternDemo {
public static void main(String[] args) {
ShapeFactory shapeFactory = new ShapeFactory();
//get an object of Circle and call its draw method.
Shape shape1 = shapeFactory.getShape("CIRCLE");
//call draw method of Circle
shape1.draw();
//get an object of Rectangle and call its draw method.
Shape shape2 = shapeFactory.getShape("SQUARE");
//call draw method of Rectangle
shape2.draw();
}
}
Step 5
Verify the output.
Inside Circle::draw() method. Inside Square::draw() method.
1.2. Abstract Factory Pattern: Creates an instance of several families of classes
Step 1: Create an interface for Shapes and Round cornered shapes.
Shape.java
RoundedRectangle.java
RoundedSquare.java
AbstractFactory.java
ShapeFactory.java
FactoryProducer.java
AbstractFactoryPatternDemo.java
Shape.java
public interface Shape {
void draw();
}
Step 2: Create concrete classes implementing the same interface.
RoundedRectangle.java
public class RoundedRectangle implements Shape {
@Override
public void draw() {
System.out.println("Inside RoundedRectangle::draw() method.");
}
}
RoundedSquare.java
public class RoundedSquare implements Shape {
@Override
public void draw() {
System.out.println("Inside RoundedSquare::draw() method.");
}
}
Rectangle.java
public class Rectangle implements Shape {
@Override
public void draw() {
System.out.println("Inside Rectangle::draw() method.");
}
}
Step 3: Create an Abstract class to get factories for Normal and Rounded Shape Objects.
AbstractFactory.java
public abstract class AbstractFactory {
abstract Shape getShape(String shapeType) ;
}
Step 4: Create Factory classes extending AbstractFactory to generate object of concrete class based on given information.
ShapeFactory.java
public class ShapeFactory extends AbstractFactory {
@Override
public Shape getShape(String shapeType){
if(shapeType.equalsIgnoreCase("RECTANGLE")) {
return new Rectangle();
}else if(shapeType.equalsIgnoreCase("SQUARE")) {
return new Square();
}
return null;
}
}
RoundedShapeFactory.java
public class RoundedShapeFactory extends AbstractFactory {
@Override
public Shape getShape(String shapeType) {
if(shapeType.equalsIgnoreCase("RECTANGLE")) {
return new RoundedRectangle();
} else if(shapeType.equalsIgnoreCase("SQUARE")) {
return new RoundedSquare();
}
return null;
}
}
Step 5: Create a Factory generator/producer class to get factories by passing an information such as Shape
FactoryProducer.java
public class FactoryProducer {
public static AbstractFactory getFactory(boolean rounded) {
if(rounded){
return new RoundedShapeFactory();
} else {
return new ShapeFactory();
}
}
}
Step 6: Use the FactoryProducer to get AbstractFactory in order to get factories of concrete classes by passing an information such as type.
AbstractFactoryPatternDemo.java
public class AbstractFactoryPatternDemo {
public static void main(String[] args) {
//get rounded shape factory
AbstractFactory shapeFactory = FactoryProducer.getFactory(false);
//get an object of Shape Rounded Rectangle
Shape shape1 = shapeFactory.getShape("RECTANGLE");
//call draw method of Shape Rectangle
shape1.draw();
//get an object of Shape Rounded Square
Shape shape2 = shapeFactory.getShape("SQUARE");
//call draw method of Shape Square
shape2.draw();
//get rounded shape factory
AbstractFactory shapeFactory1 = FactoryProducer.getFactory(true);
//get an object of Shape Rectangle
Shape shape3 = shapeFactory1.getShape("RECTANGLE");
//call draw method of Shape Rectangle
shape3.draw();
//get an object of Shape Square
Shape shape4 = shapeFactory1.getShape("SQUARE");
//call draw method of Shape Square
shape4.draw();
}
}
Step 7: Verify the output.
Inside Rectangle::draw() method. Inside Square::draw() method. Inside RoundedRectangle::draw() method. Inside RoundedSquare::draw() method.
1.3. Singleton Pattern: A class of which only a single instance can exist
Step 1: Create a Singleton Class.
SingleObject.java
SingletonPatternDemo.java
Verify the output.
SingleObject.java
public class SingleObject {
//create an object of SingleObject
private static SingleObject instance = new SingleObject();
//make the constructor private to ensure this class cannot be instantiated
private SingleObject() {
}
//Get the only object available
public static SingleObject getInstance() {
return instance;
}
public void showMessage() {
System.out.println("Hello World!");
}
}
Step 2: Get the only object from the singleton class.
SingletonPatternDemo.java
public class SingletonPatternDemo {
public static void main(String[] args) {
//Get the only object available
SingleObject object = SingleObject.getInstance();
//Show the message
object.showMessage();
}
}
Step 3
Verify the output.
Hello World!
1.4. Object Pool Pattern: Avoid expensive acquisition and release of resources by recycling objects that are no longer in use
[Code examples are coming soon...]
1.5. Prototype Pattern: A fully initialized instance to be copied or cloned
[Code examples are coming soon...]
1.6. Builder Pattern: Separates object construction from its representation
[Code examples are coming soon...]
2. Structural Design PatternsThese design patterns concern class and object composition. Concept of inheritance is used to compose interfaces and define ways to compose objects to obtain new functionalities.
[Code examples are coming soon...]
2.2. Bridge Pattern: Separates an object's interface from its implementation
2.3. Composite Pattern: A tree structure of simple and composite objects
2.4. Decorator Pattern: Add responsibilities to objects dynamically
2.5. Facade Pattern: A single class that represents an entire subsystem
2.6. Flyweight Pattern: A fine-grained instance used for efficient sharing
2.7. Private Class Data: Restricts accessor / mutator access
2.8. Proxy Pattern: An object representing another object
- Behavioral Design Patterns
These design patterns are specifically concerned with communication between objects.- Chain Of Responsibility Pattern: A way of passing a request between a chain of objects
- Command Pattern: Encapsulate a command request as an object
- Interpreter Pattern: A way to include language elements in a program
- Iterator Pattern: Sequentially access the elements of a collection
- Mediator Pattern: Defines simplified communication between classes
- Memento Pattern: Capture and restore an object's internal state
- Null Object: Designed to act as a default value of an object
- Observer Pattern: A way of notifying change to a number of classes
- State Pattern: Alter an object's behaviour when its state changes
- Strategy Pattern: Encapsulates an algorithm inside a class
- Template Pattern: Defer the exact steps of an algorithm to a subclass
- Visitor Pattern: Defines a new operation to a class without change
- J2EE Design Patterns
These design patterns are specifically concerned with the presentation layer along with relevant logics and presentation functionalities. These patterns are identified by Sun Java Center. - MVC Pattern: Wraps-up and connect Model, View and Controller in application architecture. Where Controller is mostly responsible for View and Data layer communication.
- Business Delegate Pattern: Used to decouple the presentation layer from the business layer to minimize the number of requests between the client and the business tiers
- Composite Entity Pattern: Represents a graph of objects, when that is updated, triggers an update for all other dependent entities in the graph
- Data Access Object Pattern: Shortened to DAO is a pattern in which objects are dedicated to the communication with the Data Layer. Often instantiate "SessionFactories" for this purpose and handle all of the logic behind communicating with the database. Standard practice is to create a DAO interface, followed by a concrete class implementing the interface and all methods defined in it.
- Front Controller Pattern: Front Controller is the first controller that receives a request that has been sent. Based on the request, it decides which controller is the most adequate to handle it and passes the request to the chosen controller. Front Controller is most often used in Web Applications in the form of a Dispatcher Servlet.
- Intercepting Filter Pattern: Filters are used before the request is even passed to relevant
controllers for processing. These filters can exist in the form of a Filter Chain. Can include one or multiple filters.
Furthermore, they run checks on authorization, authentication,
supported browsers, whether the request path violates any constraints
and restrictions etc.
- Service Locator Pattern: Often seen in Web Applications, this pattern is used to decouple the Service Consumers and the concrete classes like DAO implementations. The pattern looks for the adequate service, saves it in cache storage to reduce the number of requests and therefore the strain on the server and provides the application with their instances.
- Transfer Object Pattern: Used to transfer objects with lots of fields and parameters in one go. It employs new objects, used only for transfering purposes, usually passed to the DAO These objects are serializable POJOs. They have fields, their respective getters and setters, and no other logic.
Comments
Post a Comment