Free Online Courses for Software Developers - MrBool
× Please, log in to give us a feedback. Click here to login
×

You must be logged to download. Click here to login

×

MrBool is totally free and you can help us to help the Developers Community around the world

Yes, I'd like to help the MrBool and the Developers Community before download

No, I'd like to download without make the donation

×

MrBool is totally free and you can help us to help the Developers Community around the world

Yes, I'd like to help the MrBool and the Developers Community before download

No, I'd like to download without make the donation

Implementing Creational Patterns in Java

See in this article what the creational standards set by the GoF are and how they can be coded in a Java platform

Software development is one of the areas that most problems occur during its process. However, a group of professionals has found that some problems occur frequently and therefore decided to create a catalog that identify how they could be resolved in the best possible way.

These professionals were four: Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides, and were dubbed the Gang of Four (GoF). In 1995 they released the book "Design Patterns - Elements of Reusable Object-Oriented Software", which quickly became recognized worldwide and today is the bedside book of any developer. The book contains twenty-three standards and currently various literatures have launched more standards.

Those who are treated in the article refer to the GoF calls creational patterns: Singleton, Abstract Factory, Prototype, Factory Method and Builder.

These patterns are called so because they take care of the life cycle of objects, such as their creation. Thus, these seek to deal in the best way to create instances of objects by encapsulating knowledge on concrete or abstracting classes as instances are created and mounted.

In the rest of this article, we will examine the first five patterns of GoF, but using the Java platform, unlike the GoF book, whichthe examples focused on the C ++ language. We will use the Eclipse IDE to assemble them.

Singleton

Golf sets the Singleton pattern as a class with only one instance and provides a global point of access to it.

Thus, it is defined as a class that should have only one instance to be used whenever necessary.

A pattern of using a classic example is when the designers define that for a given system must be used a single file system: this is important when you want a centralized management capabilities.

The example in Listing 1 has a private constructor that can not be initialized. When there is an attempt to create an instance of the class, it is first checked if there is already one, and if so, returns that instance. If not, it will be created and returned.

Listing 1. Example implementation Singleton pattern

package com.mrbool.singleton;
 
public class CreateResourcesPool {
      private static CreateResourcesPool _pool;
 
      private CreateResourcesPool() {
      }
 
      public static CreateResourcesPool getPoolDeRecursos() {
            // Lazy initialization
            if (_pool == null) {
                  _pool = new CreateResourcesPool();
                  System.out.println("A resources pool was created to the application.");
            } else {
                  System.out.print("A resources pool was already created to the application.");
            }
            return _pool;
      }
}
 
package com.mrbool.singleton;
 
class SingletonPatternEx {
      public static void main(String[] args) {
            System.out.println("***Singleton Pattern Example***\n");
            System.out.println("Trying to create a resources pool to the application.");
            CreateResourcesPool p1 = CreateResourcesPool.getPoolDeRecursos();
            System.out.println("Trying to create another resources pool to the application");
            CreateResourcesPool p2 = CreateResourcesPool.getPoolDeRecursos();
            if (p1 == p2) {
                  System.out.println("p1 and p2 are the same instances.");
            }
      }
}

In Figure 1 we have code output and Figure 2 we have the package explorer of Eclipse.

Figure 1. Standard implementation Output Singleton.

Figure 2. Package Explorer in Eclipse to implement the Singleton.

The code of Listing 1 has what is called a lazy initialization or a late start because the instance of this Singleton class will not be created until the getPoolDeRecursos() method is called.

The big problem of the proposed implementation is that it is not thread safe. That is, there may be a situation in which two or more threads are created at the same time and thus able to create more than one instance of the Singleton class.

There is more than one way to create Singletons that are thread safe: follow in Listing 2 is an example using synchronized.

Listing 2. Example of implementing the Singleton pattern using synchronized.

public static synchronized CreateResourcesPool getResourcesPool()
  {
    // Code that returns the instance
  }

The code prevents the creation of more than one instance. However, it has performance problems due to the use of synchronized.

Another way is to use a method of the type initialization eager, unlike the previous lazy initialization, as shown in the example in Listing 3.

Listing 3. Example of implementing the Singleton pattern using early initialization.

  class CreateResourcesPool
  {
     // Initialization Early (or late Startup)
     private static CreateResourcesPool _pool CreateResourcesPool = new ();
   
     // The constructor was defined as being private to avoid the use of new
     private CreateResourcesPool () {}
   
     // Global access point to the resource pool
     public static CreateResourcesPool getPoolDeRecursos ()
     {
        _pool return;
     }
  }

In the presented solution, an object of the Singleton class is always instantiated. The source of the problem is that, depending on the situation, this class created would never need to be used.

The Listing 4 code is considered the ideal, with a different approach than the others.

Listing 4. Example of implementing the Singleton pattern using nested classes.

  class CreateResourcesPool
  {
     private static CreateResourcesPool _pool;
   
     private CreateResourcesPool () {}
   
     private static class SingletonHelper {
        // Class nested referenced after calling getPoolDeRecursos ()
        private static final CreateResourcesPool _pool CreateResourcesPool = new ();
     }
   
     public static CreateResourcesPool getPoolDeRecursos ()
     {
         SingletonHelper._pool return;
     }
  }

Abstract Factory

The GoF sets the Abstract Factory as a standard that provides an interface for creating families of related or dependent objects without specifying their concrete classes.

This pattern has an encapsulation mechanism for grouping individual plants. In this process, an interface is used to create related objects, so you can not directly call the concrete class.

The standard benefit of the Abstract Factory is the possibility of replacing the concrete implementations without changing the user code. The downside is that the debugging becomes very complex.

The example of Listing 5 to 8 has some films divided by gender and their factories which are responsible for product family instantiation of the same category.

Listing 5. Interfaces for the products and for the factory.

package com.mrbool.abstractfactory;
  public interface IAmericanMovie {
         String MovieName();
  }
   
package com.mrbool.abstractfactory;
  public interface ICanadianMovie {
         String MovieName();
  }               
   
 package com.mrbool.abstractfactory;
  public interface IMoviesFactory {
         ICanadianMovie getCanadianMovie();
         IAmericanMovie getFilmeAmericano();
  }

Listing 6. Implementation of products (films) that will be created by the factory.

package com.mrbool.abstractfactory;
  public class CanadianActionMovie ICanadianMovie implements {
         Override
         public String movieName ()
         {
               return "The Proposal";
         }
  }
   
package com.mrbool.abstractfactory;
  public class implements CanadianMovieComedia ICanadianMovie {
         Override
         public String movieName ()
         {
               return "If I Were You";
         }
  }
   
 package com.mrbool.abstractfactory;
  public class AmericanActionMovie IAmericanMovie implements {
         Override
         public String movieName ()
         {
               return "Star Wars (2016)";
         }
  }
   
 package com.mrbool.abstractfactory;
  public class implements AmericanComedyMovie IAmericanMovie {
         Override
         public String movieName ()
         {
               return "Everybody in Panic 2 (2014)";
         }
  }

Listing 7. Implementation of factorys returning the products.

package com.mrbool.abstractfactory;
  public class implements ActionMoviesFactory IMoviesFactory {
         
         public ICanadianMovie getCanadianMovie ()
         {
               return new CanadianActionMovie ();
         }
   
         public IAmericanMovie getFilmeAmericano ()
         {
               return new AmericanActionMovie ();
         }
         
  }
   
package com.mrbool.abstractfactory;
  public class implements FilmesComediaFactory IMoviesFactory {
   
         public ICanadianMovie getCanadianMovie ()
         {
               return new CanadianMovieComedia ();
         }
   
         public IAmericanMovie getFilmeAmericano ()
         {
               return new AmericanComedyMovie ();
         }
         
  }

Listing 8. Implementation of the main code that creates the factories and products.

package com.mrbool.abstractfactory;
   
  public class AbstractFactoryPatternEx {
   
    public static void main (String [] args) {
   
      System.out.println ( "*** Standard Example Abstract Factory ***");
      ActionMoviesFactory actionMovie ActionMoviesFactory = new ();
      ICanadianMovie actionMovieCA actionMovie.getCanadianMovie = ();
      IAmericanMovie actionMovieUS actionMovie.getFilmeAmericano = ();
   
      System.out.println ( "\ nThe cataloged Action films are:");
      System.out.println (actionMovieCA.movieName ());
      System.out.println (actionMovieUS.movieName ());
  
      FilmesComediaFactory comedyMovie FilmesComediaFactory = new ();
      ICanadianMovie comedyMovieCA comedyMovie.getCanadianMovie = ();
      IAmericanMovie comedyMovieUS comedyMovie.getFilmeAmericano = ();
   
      System.out.println ( "\ nThe cataloged Comedy films are ::");
      System.out.println (comedyMovieCA.movieName ());
      System.out.println (comedyMovieUS.movieName ());
  }
   
}

This pattern is used when the system does not have to worry about how products should be created. When we deal with several factories, we can separate concrete classes and make the switch to products more easily.

Prototype

The GoF sets the Prototype as a standard that specifies the types of objects to be created using a prototype. It provides an alternative method to instantiate new objects by copying or cloning an existing instance. Creating a new instance is quite expensive, so this pattern helps solve this problem.

A classic example of the Prototype pattern is when you have a standard document: when you need to use it again, rather than create it again, just make a copy of it with the necessary changes.

The example of Listings 9 to 12 has been called a prototype car with concrete Prototypes Ford and Chevrolet, which need to implement the clone() method defined in the car. It can be seen that the car is created with a standard price, so we need to modify the price in each of the models. The customer is PrototypePatternEx.

Listing 9. Implementation of Prototype car.

package com.mrbool.prototype;
   
  import java.util.Random;
   
  public abstract class Car implements Cloneable {
         public String templateName;
         public int price;
   
         public String getModelName ()
         {
               templateName return;
         }
   
         public void setModelName (String templateName)
         {
               this.ModelName = templateName;
         }
   
         public static int setPrice ()
         {
               int price = 0;
               Random r = new Random();
               r.nextInt p = int (100,000);
               price = p;
   
               return price;
         }
   
         Car public clone () throws CloneNotSupportedException
         {
               return (car) super.clone ();
         }
  }

Listing 10. Implementation of concrete Ford Prototype car.

package com.mrbool.prototype;
   
  public class Ford extends Car {
         Public Ford (String m)
         {
               templateName = m;
         }
   
         Override
         Car public clone () throws CloneNotSupportedException
         {
               return (Ford) super.clone ();
         }
  }

Listing 11. Implementation of concrete Chevrolet Prototype car.

package com.mrbool.prototype;
   
  public class Chevrolet extends Car {
         public Chevrolet (String m)
         {
               templateName = m;
         }
   
         Override
         Car public clone () throws CloneNotSupportedException
         {
               return (Chevrolet) super.clone ();
         }
  }

Listing 12. Implementation of the main code that tests Prototypes.

package com.mrbool.prototype;
   
  public class PrototypePatternEx {
                  
    public static void main (String args []) {throws CloneNotSupportedException
               
      System.out.println ( "*** default *** Example Prototype \ n");
      Car chevrolet = new Chevrolet("Cross Sport v6");
      chevrolet.price = 100000;
      Car ford = new Ford("Focus 2.0");
      ford.price = 500000;
   
      Car bc1;
      // Object Chevrolet Clone
      bc1 = chevrolet.clone();
   
      // Setting price that is higher than 100,000
      bc1.price = chevrolet.price + car.setPrice(100000);
      System.out.println ( "Car name:" + bc1.getModelName() + "Price Car:" + bc1.price);
   
      // Clone Object Ford
      bc1 = ford.clone();
 
      // Setting price that is higher than 500,000
      bc1.price = ford.price + car.setPrice(50000);
      System.out.println ("Car name:" + bc1.getModelName() + "Price Car:" + bc1.price);
               
   }
         
  }

This pattern is often used when the system does not have to worry about the mechanism of creation products and when you need to instantiate classes at runtime . The problem with Prototype is that it is always necessary to implement the clone mechanism in each subclass.

Factory Method

Factory Method is a standard that defines an interface for creating an object but lets subclasses decide which class to instantiate.

An example of using the Factory Method are Windows applications that have different database such as Oracle and SQL Server. So whenever you need to enter information into the database you need to create a SqlConnection or OracleConnection. If this is done in an if-else we will have a lot of code and complicated maintenance.

To solve this problem just use the Factory Method, which has a basic structure with an abstract class. Subclasses are derived from this class and will have the responsibility of the instantiation process. Note in Listings 13 to 18.

Listing 13. An interface standard for the products to be created

package com.mrbool.factorymethod;
   
  public interface IAnimal {
         void notify();
  }

Listing 14. Implementation of pet dog

package com.mrbool.factorymethod;
   
  public class Dog implements IAnimal {
         Override
         public void notify()
         {
               System.out.println("Dog barks!");
         }
   
  }

Listing 15. Cat animal Implementation.

package com.mrbool.factorymethod;
   
  public class Cat implements IAnimal {
         Override
         public void notify()
         {
               System.out.println("Cat meow!");
         }
  }

Listing 16. Abstract implementation for creating the Factory Method .

package com.mrbool.factorymethod;
   
  public abstract class IAnimalFactory {
         public abstract IAnimal getAnimalType(String type) throws Exception;
  }

Listing 17. Implementation of concrete Factory Method that creates animals.

package com.mrbool.factorymethod;
   
  public class ConcreteFactory extends IAnimalFactory {
         Override
         public IAnimal getAnimalType(String type) throws Exception
         {
               switch (type)
               {
                      case "Cat":
                             return new Cat();
                      case "Dog":
                             return new Dog();
                      default:
                             throw new Exception ( "The Animal type" + type + "can not be instantiated.");
               }
         }
  }

Listing 18. Implementation of the main code that tests the Factory Method.

package com.mrbool.factorymethod;
   
  public class FactoryPatternEx {
         public static void main (String [] args) throws Exception
         {
               System.out.println("*** Example Standard Factory: *** \ n");
               
               IAnimalFactory animalFactory = new ConcreteFactory();
               
               IAnimal cat = animalFactory.getAnimalType("Cat");
               gato.notify();
               IAnimal dog = animalFactory.getAnimalType("Dog");
               cachorro.notify ();
               
               // In an attempt to create a duck an exception is returned because there is not an animal duck type.
               IAnimal duck = animalFactory.getAnimalType("Duck");
               pato.notify();
         }
  }

This pattern is useful when the responsibility of the object creation must be subclasses and when we want the system to have less coupling.

Builder

The Builder pattern separates the construction of a complex object from its representation, since the same construction process can create different representations. It is useful when a creational algorithm of a complex object is independent of the assembly of the parts of the object.

The present example in Listings 19 to 24 has the IBuilder, Car, Motorcycle, Product and Director, where Car and Moto implement IBuilder interface, which in turn is used to create parts of the Product object, which represents the complex object that is under construction.

The assembly process is described in the Product Listing 22. Linked List Data Structure product was used for this assembly operation. Car and Moto are concrete implementations that implement the IBuilder interface, so the use of methods buildCarcass(), insertTires() addHeadlights() and getVehicle(). The first three are used to construct the body of the vehicle wheels and insert the lights. Already getVehicle() method returns the product, and finally, Director is responsible for building the vehicle with IBuilder interface.

Listing 19. Interface Builder

package com.mrbool.builder;
   
  public interface IBuilder {
         void buildCarcass();
         void insertTires();
         void addHeadlights();
         Product getVehicle();
  }

Listing 20. Implementation of concrete car for the Builder interface.

package com.mrbool.builder;
   
  public class Car implements IBuilder {
         private Product product = new Product();
   
         Override
         public void buildCarcass()
         {
               produto.add ("Car of the housing built!");
         }
   
         Override
         public void insertTires()
         {
               produto.add ("4-wheel added!");
         }
   
         Override
         public void addHeadlights()
         {
               produto.add("6 lights inserted!");
         }
   
         Override
         public getVehicle Product()
         {
               return product;
         }
  }

Listing 21. Implementation of concrete Moto for the Builder interface.

package com.mrbool.builder;
   
  public class Moto implements IBuilder {
         private Product product = new Product();
   
         Override
         public void buildCarcass()
         {
               produto.add("Moto Housing built!");
         }
   
         Override
         public void insertTires()
         {
               produto.add("2 wheels added!");
         }
   
         Override
         public void addHeadlights()
         {
               produto.add("2 headlights inserted!");
         }
   
         Override
         public getVehicle Product()
         {
               return product;
         }
  }

Listing 22. Class that displays information and adds the parts of the product.

package com.mrbool.builder;
   
  import java.util.LinkedList;
   
  public class Product {
   
         private LinkedList <String> vehicleParts;
   
         public Product ()
         {
               vehicleParts = new LinkedList<String> ();
         }
   
         public void add (String vehiclePart)
         {
               // Adds vehicle parts
               vehicleParts.addLast (vehiclePart);
         }
   
         public void display ()
         {
               System.out.println ( "\ n Complete product:");
   
               for (int i = 0; i < vehicleParts.size (); i ++)
               {
                      System.out.println (vehicleParts.get(i));
               }
         }
  }

Listing 23. Class Director responsible for the Builder construction standard algorithm.

package  com.mrbool.builder;
   
  public class Director {
         IBuilder meuBuilder;
   
         // Method to the series of steps for construction of the vehicle
         public void build(IBuilder builder)
         {
               meuBuilder = builder;
               meuBuilder.buildCarcass();
               meuBuilder.insertTires();
               meuBuilder.addHeadlights();
         }
  }

Listing 24. Implementation of the main code that tests the Builder.

package com.mrbool.builder;
   
  public class BuilderPatternEx {
         public static void main (String [] args)
         {
               System.out.println ( "*** Standard Builder Example: *** \ n");
               Director Director = new Director ();
               IBuilder carroBuilder = new Car();
               IBuilder motoBuilder = new Moto();
   
               // Building a Car
               director.build(carroBuilder);
               Product p1 = carroBuilder.getVehicle();
               p1.show();
   
               // Building a Motorcycle
               director.build(motoBuilder);
               Product p2 = motoBuilder.getVehicle();
               p2.show();
         }
  }

Conclusion

It can be seen that the complex process of building is hidden, so the focus is on how the product is made. In general, there is only one method that returns a complex object and other methods will be responsible for partial creation process.

See how using standards is something easy! This is because they help us deal with the complexity of the code.

The other standards that the book deals are also important, but very specific. With patterns learned here can fully optimize our codes.

I hope you enjoyed the article. Please apply these patterns in your code.

Bibliography

[1] Erich Gamma, Ricard Helm, Ralph Johnson, John Vlissides. Design Patterns: Elements of Reusable Object-Oriented Software (Addison-Wesley, 1994).

[2] Eric Freeman, Elisabeth Robson, Bert Bates, Kathy Sierra. Head First Design Patterns. O'Reilly Media, 2004.

[3] Deepak, A .; Dan, M .; John C .; Core J2EE Patterns: Best Practices and Design Strategies (2nd Edition). Prentice Hall, 2003.



Fabrí­cio Galdino is a software expert and has worked with IT analysis and business development for more than five years. It has extensive experience with testing, back and front-end technologies.

What did you think of this post?
Services
[Close]
To have full access to this post (or download the associated files) you must have MrBool Credits.

  See the prices for this post in Mr.Bool Credits System below:

Individually – in this case the price for this post is US$ 0,00 (Buy it now)
in this case you will buy only this video by paying the full price with no discount.

Package of 10 credits - in this case the price for this post is US$ 0,00
This subscription is ideal if you want to download few videos. In this plan you will receive a discount of 50% in each video. Subscribe for this package!

Package of 50 credits – in this case the price for this post is US$ 0,00
This subscription is ideal if you want to download several videos. In this plan you will receive a discount of 83% in each video. Subscribe for this package!


> More info about MrBool Credits
[Close]
You must be logged to download.

Click here to login