Jul 3, 2013

Best tutorial - Java Design patterns (Part 2) - Creational Design Patterns

Singleton Pattern

 Motivation

Sometimes it's important to have only one instance for a class. For example, in a system there should be only one window manager (or only a file system or only a print spooler). Usually singletons are used for centralized management of internal or external resources and they provide a global point of access to themselves.
The singleton pattern is one of the simplest design patterns: it involves only one class which is responsible to instantiate itself, to make sure it creates not more than one instance; in the same time it provides a global point of access to that instance. In this case the same instance can be used from everywhere, being impossible to invoke directly the constructor each time.

Intent

  • Ensure that only one instance of a class is created.
  • Provide a global point of access to the object.

Implementation

The implementation involves a static member in the "Singleton" class, a private constructor and a static public method that returns a reference to the static member.
Singleton Implementation - UML Class Diagram
The Singleton Pattern defines a getInstance operation which exposes the unique instance which is accessed by the clients. getInstance() is is responsible for creating its class unique instance in case it is not created yet and to return that instance.
class Singleton
{
 private static Singleton instance;
 private Singleton()
 {
  ...
 }

 public static synchronized Singleton getInstance()
 {
  if (instance == null)
   instance = new Singleton();

  return instance;
 }
 ...
 public void doSomething()
 {
  ... 
 }
}
You can notice in the above code that getInstance method ensures that only one instance of the class is created. The constructor should not be accessible from the outside of the class to ensure the only way of instantiating the class would be only through the getInstance method.
The getInstance method is used also to provide a global point of access to the object and it can be used in the following manner:
Singleton.getInstance().doSomething();

Applicability & Examples

According to the definition the singleton pattern should be used when there must be exactly one instance of a class, and when it must be accessible to clients from a global access point. Here are some real situations where the singleton is used:

Example 1 - Logger Classes

The Singleton pattern is used in the design of logger classes. This classes are ussualy implemented as a singletons, and provides a global logging access point in all the application components without being necessary to create an object each time a logging operations is performed.

Example 2 - Configuration Classes

The Singleton pattern is used to design the classes which provides the configuration settings for an application. By implementing configuration classes as Singleton not only that we provide a global access point, but we also keep the instance we use as a cache object. When the class is instantiated( or when a value is read ) the singleton will keep the values in its internal structure. If the values are read from the database or from files this avoids the reloading the values each time the configuration parameters are used.

 ----------

Factory Pattern

Motivation

The Factory Design Pattern is probably the most used design pattern in modern programming languages like Java and C#. It comes in different variants and implementations. If you are searching for it, most likely, you'll find references about the GoF patterns: Factory Method and Abstract Factory.

In this article we'll describe a flavor of factory pattern commonly used nowdays. You can also check the original Factory Method pattern which is very similar.

Intent

  • creates objects without exposing the instantiation logic to the client.
  • refers to the newly created object through a common interface

Implementation

Factory Implementation - UML Class Diagram
The implementation is really simple
  • The client needs a product, but instead of creating it directly using the new operator, it asks the factory object for a new product, providing the information about the type of object it needs.
  • The factory instantiates a new concrete product and then returns to the client the newly created product(casted to abstract product class).
  • The client uses the products as abstract products without being aware about their concrete implementation.

---------

Abstract Factory

Motivation

Modularization is a big issue in today's programming. Programmers all over the world are trying to avoid the idea of adding code to existing classes in order to make them support encapsulating more general information. Take the case of a information manager which manages phone number. Phone numbers have a particular rule on which they get generated depending on areas and countries. If at some point the application should be changed in order to support adding numbers form a new country, the code of the application would have to be changed and it would become more and more complicated.
In order to prevent it, the Abstract Factory design pattern is used. Using this pattern a framework is defined, which produces objects that follow a general pattern and at runtime this factory is paired with any concrete factory to produce objects that follow the pattern of a certain country. In other words, the Abstract Factory is a super-factory which creates other factories (Factory of factories).

Intent

  • Abstract Factory offers the interface for creating a family of related objects, without explicitly specifying their classes.

Implementation

The pattern basically works as shown below, in the UML diagram:
Abstract Factory Implementation - UML Class Diagram

The classes that participate to the Abstract Factory pattern are:
  • AbstractFactory - declares a interface for operations that create abstract products.
  • ConcreteFactory - implements operations to create concrete products.
  • AbstractProduct - declares an interface for a type of product objects.
  • Product - defines a product to be created by the corresponding ConcreteFactory; it implements the AbstractProduct interface.
  • Client - uses the interfaces declared by the AbstractFactory and AbstractProduct classes.
The AbstractFactory class is the one that determines the actual type of the concrete object and creates it, but it returns an abstract pointer to the concrete object just created. This determines the behavior of the client that asks the factory to create an object of a certain abstract type and to return the abstract pointer to it, keeping the client from knowing anything about the actual creation of the object.
The fact that the factory returns an abstract pointer to the created object means that the client doesn't have knowledge of the object's type. This implies that there is no need for including any class declarations relating to the concrete type, the client dealing at all times with the abstract type. The objects of the concrete type, created by the factory, are accessed by the client only through the abstract interface.
The second implication of this way of creating objects is that when the adding new concrete types is needed, all we have to do is modify the client code and make it use a different factory, which is far easier than instantiating a new type, which requires changing the code wherever a new object is created.
The classic implementation for the Abstract Factory pattern is the following:
abstract class AbstractProductA{
 public abstract void operationA1();
 public abstract void operationA2();
}

class ProductA1 extends AbstractProductA{
 ProductA1(String arg){
  System.out.println("Hello "+arg);
 } // Implement the code here
 public void operationA1() { };
 public void operationA2() { };
}

class ProductA2 extends AbstractProductA{
 ProductA2(String arg){
  System.out.println("Hello "+arg);
 } // Implement the code here
 public void operationA1() { };
 public void operationA2() { };
}

abstract class AbstractProductB{
 //public abstract void operationB1();
 //public abstract void operationB2();
}

class ProductB1 extends AbstractProductB{
 ProductB1(String arg){
  System.out.println("Hello "+arg);
 } // Implement the code here
}

class ProductB2 extends AbstractProductB{
 ProductB2(String arg){
  System.out.println("Hello "+arg);
 } // Implement the code here
}

abstract class AbstractFactory{
 abstract AbstractProductA createProductA();
 abstract AbstractProductB createProductB();
}

class ConcreteFactory1 extends AbstractFactory{
 AbstractProductA createProductA(){
  return new ProductA1("ProductA1");
 }
 AbstractProductB createProductB(){
  return new ProductB1("ProductB1");
 }
}

class ConcreteFactory2 extends AbstractFactory{
 AbstractProductA createProductA(){
  return new ProductA2("ProductA2");
 }
 AbstractProductB createProductB(){
  return new ProductB2("ProductB2");
 }
}

//Factory creator - an indirect way of instantiating the factories
class FactoryMaker{
 private static AbstractFactory pf=null;
 static AbstractFactory getFactory(String choice){
  if(choice.equals("a")){
   pf=new ConcreteFactory1();
  }else if(choice.equals("b")){
    pf=new ConcreteFactory2();
   } return pf;
 }
}

// Client
public class Client{
 public static void main(String args[]){
  AbstractFactory pf=FactoryMaker.getFactory("a");
  AbstractProductA product=pf.createProductA();
  //more function calls on product
 }
}

Applicability & Examples

We should use the Abstract Factory design pattern when:
  • the system needs to be independent from the way the products it works with are created.
  • the system is or should be configured to work with multiple families of products.
  • a family of products is designed to work only all together.
  • the creation of a library of products is needed, for which is relevant only the interface, not the implementation, too.

Phone Number Example

The example at the beginning of the article can be extended to addresses, too. The AbstractFactory class will contain methods for creating a new entry in the information manager for a phone number and for an address, methods that produce the abstract products Address and PhoneNumber, which belong to AbstractProduct classes. The AbstractProduct classes will define methods that these products support: for the address get and set methods for the street, city, region and postal code members and for the phone number get and set methods for the number.
The ConcreteFactory and ConcreteProduct classes will implement the interfaces defined above and will appear in our example in the form of the USAddressFactory class and the USAddress and USPhoneNumber classes. For each new country that needs to be added to the application, a new set of concrete-type classes will be added. This way we can have the EnglandAddressFactory and the EnglandAddress and EnglandPhoneNumber that are files for English address information.

Pizza Factory Example

Another example, this time more simple and easier to understand, is the one of a pizza factory, which defines method names and returns types to make different kinds of pizza. The abstract factory can be named AbstractPizzaFactory, RomeConcretePizzaFactory and MilanConcretePizzaFactory being two extensions of the abstract class. The abstract factory will define types of toppings for pizza, like pepperoni, sausage or anchovy, and the concrete factories will implement only a set of the toppings, which are specific for the area and even if one topping is implemented in both concrete factories, the resulting pizzas will be different subclasses, each for the area it was implemented in.

----------

Builder Pattern



Motivation

The more complex an application is the complexity of classes and objects used increases. Complex objects are made of parts produced by other objects that need special care when being built. An application might need a mechanism for building complex objects that is independent from the ones that make up the object. If this is the problem you are being confronted with, you might want to try using the Builder (or Adaptive Builder) design pattern.
This pattern allows a client object to construct a complex object by specifying only its type and content, being shielded from the details related to the object�s representation. This way the construction process can be used to create different representations. The logic of this process is isolated form the actual steps used in creating the complex object, so the process can be used again to create a different object form the same set of simple objects as the first one.

Intent

  • Defines an instance for creating an object but letting subclasses decide which class to instantiate
  • Refers to the newly created object through a common interface

Implementation

The Builder design pattern uses the Factory Builder pattern to decide which concrete class to initiate in order to build the desired type of object, as we will see below in the UML diagram:
Builder Pattern - UML Class Diagram

The participants classes in this pattern are:
  • The Builder class specifies an abstract interface for creating parts of a Product object.
  • The ConcreteBuilder constructs and puts together parts of the product by implementing the Builder interface. It defines and keeps track of the representation it creates and provides an interface for saving the product.
  • The Director class constructs the complex object using the Builder interface.
  • The Product represents the complex object that is being built.
The client, that may be either another object or the actual client that calls the main() method of the application, initiates the Builder and Director class. The Builder represents the complex object that needs to be built in terms of simpler objects and types. The constructor in the Director class receives a Builder object as a parameter from the Client and is responsible for calling the appropriate methods of the Builder class. In order to provide the Client with an interface for all concrete Builders, the Builder class should be an abstract one. This way you can add new types of complex objects by only defining the structure and reusing the logic for the actual construction process. The Client is the only one that needs to know about the new types, the Director needing to know which methods of the Builder to call.
The following example discusses the case of a text converting application:
Builder Pattern Example - UML Class Diagram The Client needs to convert a document from RTF format to ASCII format. There for, it calls the method createASCIIText that takes as a parameter the document that will be converted. This method calls the concrete builder, ASCIIConverter, that extends the Builder, TextConverter, and overrides its two methods for converting characters and paragraphs, and also the Director, RTFReader, that parses the document and calls the builder�s methods depending on the type of token encountered. The product, the ASCIIText, is built step by step, by appending converted characters.
//Abstract Builder
class abstract class TextConverter{
 abstract void convertCharacter(char c);
 abstract void convertParagraph();
}

// Product
class ASCIIText{
 public void append(char c){ //Implement the code here }
}

//Concrete Builder
class ASCIIConverter extends TextConverter{
 ASCIIText asciiTextObj;//resulting product

 /*converts a character to target representation and appends to the resulting*/
 object void convertCharacter(char c){
  char asciiChar = new Character(c).charValue();
   //gets the ascii character
  asciiTextObj.append(asciiChar);
 }
 void convertParagraph(){}
 ASCIIText getResult(){
  return asciiTextObj;
 }
}

//This class abstracts the document object
class Document{
 static int value;
 char token;
 public char getNextToken(){
  //Get the next token
  return token;
 }
}

//Director
class RTFReader{
 private static final char EOF='0'; //Delimitor for End of File
 final char CHAR='c';
 final char PARA='p';
 char t;
 TextConverter builder;
 RTFReader(TextConverter obj){
  builder=obj;
 }
 void parseRTF(Document doc){
  while ((t=doc.getNextToken())!= EOF){
   switch (t){
    case CHAR: builder.convertCharacter(t);
    case PARA: builder.convertParagraph();
   }
  }
 }
}

//Client
public class Client{
 void createASCIIText(Document doc){
  ASCIIConverter asciiBuilder = new ASCIIConverter();
  RTFReader rtfReader = new RTFReader(asciiBuilder);
  rtfReader.parseRTF(doc);
  ASCIIText asciiText = asciiBuilder.getResult();
 }
 public static void main(String args[]){
  Client client=new Client();
  Document doc=new Document();
  client.createASCIIText(doc);
  system.out.println("This is an example of Builder Pattern");
 }
}


Applicability & Examples

Builder Pattern is used when:
  • the creation algorithm of a complex object is independent from the parts that actually compose the object
  • the system needs to allow different representations for the objects that are being built

Example 1 - Vehicle Manufacturer.

Let us take the case of a vehicle manufacturer that, from a set of parts, can build a car, a bicycle, a motorcycle or a scooter. In this case the Builder will become the VehicleBuilder. It specifies the interface for building any of the vehicles in the list above, using the same set of parts and a different set of rules for every type of type of vehicle. The ConcreteBuilders will be the builders attached to each of the objects that are being under construction. The Product is of course the vehicle that is being constructed and the Director is the manufacturer and its shop.

Example 1 - Students Exams.

If we have an application that can be used by the students of a University to provide them with the list of their grades for their exams, this application needs to run in different ways depending on the user that is using it, user that has to log in. This means that, for example, the admin needs to have some buttons enabled, buttons that needs to be disabled for the student, the common user. The Builder provides the interface for building form depending on the login information. The ConcreteBuilders are the specific forms for each type of user. The Product is the final form that the application will use in the given case and the Director is the application that, based on the login information, needs a specific form.

--------------

Prototype Pattern


Motivation

Today’s programming is all about costs. Saving is a big issue when it comes to using computer resources, so programmers are doing their best to find ways of improving the performance When we talk about object creation we can find a better way to have new objects: cloning. To this idea one particular design pattern is related: rather than creation it uses cloning. If the cost of creating a new object is large and creation is resource intensive, we clone the object.
The Prototype design pattern is the one in question. It allows an object to create customized objects without knowing their class or any details of how to create them. Up to this point it sounds a lot like the Factory Method pattern, the difference being the fact that for the Factory the palette of prototypical objects never contains more than one object.

Intent

  • specifying the kind of objects to create using a prototypical instance
  • creating new objects by copying this prototype
    • Implementation

      The pattern uses abstract classes, as we will see below and only three types of classes making its implementation rather easy.
      Prototype Implementation - UML Class DiagramThe classes participating to the Prototype Pattern are:

      • Client - creates a new object by asking a prototype to clone itself.
      • Prototype - declares an interface for cloning itself.
      • ConcretePrototype - implements the operation for cloning itself.
      • The process of cloning starts with an initialized and instantiated class. The Client asks for a new object of that type and sends the request to the Prototype class. A ConcretePrototype, depending of the type of object is needed, will handle the cloning through the Clone() method, making a new instance of itself.
        Here is a sample code for the Prototype pattern:
        public interface Prototype {
         public abstract Object clone ( );
        }
        
         
        
        public class ConcretePrototype implements Prototype {
         public Object clone() {
          return super.clone();
         }
        }
        
        public class Client {
        
         public static void main( String arg[] ) 
         {
          ConcretePrototype obj1= new ConcretePrototype ();
          ConcretePrototype obj2 = ConcretePrototype)obj1.clone();
         }
        
        }
        
        This example is rather trivial, but the real use of the pattern comes when we don’t know what we’re actually cloning. For example if we need the newly created object to be stored in a hashtable we can use it like this:
        // Violation of Likov's Substitution Principle
        class Rectangle
        {
         protected int m_width;
         protected int m_height;
        
         public void setWidth(int width){
          m_width = width;
         }
        
         public void setHeight(int height){
          m_height = height;
         }
        
        
         public int getWidth(){
          return m_width;
         }
        
         public int getHeight(){
          return m_height;
         }
        
         public int getArea(){
          return m_width * m_height;
         } 
        }
        
        class Square extends Rectangle 
        {
         public void setWidth(int width){
          m_width = width;
          m_height = width;
         }
        
         public void setHeight(int height){
          m_width = height;
          m_height = height;
         }
        
        }
        
        class LspTest
        {
         private static Rectangle getNewRectangle()
         {
          // it can be an object returned by some factory ... 
          return new Square();
         }
        
         public static void main (String args[])
         {
          Rectangle r = LspTest.getNewRectangle();
                
          r.setWidth(5);
          r.setHeight(10);
          // user knows that r it's a rectangle.
          // It assumes that he's able to set the width and height as for the base class
        
          System.out.println(r.getArea());
          // now he's surprised to see that the area is 100 instead of 50.
         }
        }
        

        Applicability & Examples

        Use Prototype Pattern when a system should be independent of how its products are created, composed, and represented, and:
        • Classes to be instantiated are specified at run-time
        • Avoiding the creation of a factory hierarchy is needed
        • It is more convenient to copy an existing instance than to create a new one.

        Example 1

        In building stages for a game that uses a maze and different visual objects that the character encounters it is needed a quick method of generating the haze map using the same objects: wall, door, passage, room... The Prototype pattern is useful in this case because instead of hard coding (using new operation) the room, door, passage and wall objects that get instantiated, CreateMaze method will be parameterized by various prototypical room, door, wall and passage objects, so the composition of the map can be easily changed by replacing the prototypical objects with different ones.
        The Client is the CreateMaze method and the ConcretePrototype classes will be the ones creating copies for different objects.

        Example 2:

        Suppose we are doing a sales analysis on a set of data from a database. Normally, we would copy the information from the database, encapsulate it into an object and do the analysis. But if another analysis is needed on the same set of data, reading the database again and creating a new object is not the best idea. If we are using the Prototype pattern then the object used in the first analysis will be cloned and used for the other analysis.
        The Client is here one of the methods that process an object that encapsulates information from the database. The ConcretePrototype classes will be classes that, from the object created after extracting data from the database, will copy it into objects used for analysis.

 -----------

Object Pool

Motivation

Performance can be sometimes the key issue during the software development and the object creation(class instantiation) is a costly step. While the Prototype pattern helps in improving the performance by cloning the objects, the Object Pool pattern offer a mechanism to reuse objects that are expensive to create.

Clients of an object pull "feel" like they are owners of a service although the service is shared among many other clients.

Intent

-reuse and share objects that are expensive to create.


Implementation

Objectpool Implementation - UML Class Schema

Implementation involves the following objects:
Reusable - Wraps the limited resource, will be shared by several clients for a limited amount of time.
Client - uses an instance of type Reusable.
ReusablePool - manage the reusable objects for use by Clients, creating and managing a pool of objects.

When a client asks for a Reusable object, the pool performs the following actions:
-    Search for an available Reusable object and if it was found it will be returned to the client.
-    If no Reusable object was found then it tries to create a new one. If this actions succeds the new Reusable object will be returned to the client.
-    If the pool was unable to create a new Reusable, the pool will wait until a reusable object will be released.

The Client is responsible to request the Reusable object as well to release it to the pool. If this action will not be performed the Reusable object will be lost, being considered unavailable by the ResourcePool.

The clients are not aware that they are sharing the Reusable object. From the client poinf of view they are the owners of a new object which comes from the Resource pool in the same way that it comes from a factory or another creational design pattern. The only difference is that the Client should mark the Reusable object as available, after it finishes to use it. It's not about releasing the objects; for example if we work with databases, when a connection is closed it's not necesarely distroyed, it means that it can be reused by another client.

Why to use it?

Basically, we'll use an object pool whenever there are several clients who needs the same stateless resource which is expensive to create.

Applicability & Examples


Lets' take the example of the database connections. It's obviosly that opening too many connections might affect the performance for several reasons:
Creating a connection is an expensive operation.
When there are too many connections opened it takes longer to create a new one and the database server will become overloaded.

Here the object pool comes in to picture to manage the connections and provide a way to reuse and share them. It can also limit the maximum number of objects that can be created.
Objectpool Example Database Connection - UML Class Schema


This pattern provide the following mechaninsm:

Connection - represent the object which is instantiated by the client. From the client perspective this object is instantiated and it handles the database operations and it is the only object visible to the client. The client is not aware that it uses  some shared connections. Internally this class does not contain any code for connecting to the database and calls ConnectionPool.aquireImpl to get a ConnectionImpl object and then delegates the request to ConnectionImpl.

ConnectionImpl is the object which implements the database operations which are exposed by Connection for the client.

ConnectionPool is the main actor to manage the connections to the database. It keeps a list of ConnectionImpl objects and instantiates new objects if this is required.

When the client needs to query the database it instantiate a new Connection object specifing the database name and the call the query method which returns a set of records. From the client point of view this is all.

When the Connection.Query methd is called it asks for a ConnectionImpl object from the ConnectionPool. The ConnectionPool tries to find and return an unused object and if it doesn't find it creates one. At this point the maximum number of connections can be limited and if it was reached the pool cand wait until one will be available or return null. In the query method the request is delegated to the ConnectionImpl object returned by the object pool. Since the request is just delegated it's recomended to have the same method signature in Connection and ConnectionImpl.

(Source: Internet)



1 comment: