Factory Patterns for Java Design Patterns Learning

Explain

In the Java (or Object-Oriented Language) world, factory patterns are widely used in projects. You may not have heard of them, but you may already be using them. Simply put, the emergence of factory mode stems from increasing the extensibility of the program and reducing the coupling degree. The so-called factory mode is the process of producing objects in the analogical code that uses the factory to produce products. Overall, the factory model is divided into the following categories:

  • Simple Factory Pattern
  • Factory Method Pattern
  • Abstract Factory Pattern

Simple Factory Pattern

We simulate a scenario where an auto factory is going to produce cars, and now it mainly produces cars and buses. The code simulation is as follows:

Firstly, "design" a prototype of automobile (define the automobile interface), which embodies the commonalities of all automobiles:

public interface Auto {
	//All cars can be driven.
	public void drive();
}

Next we "design" two kinds of cars: cars and buses.

//Sedan
public class Car implements Auto{
	@Override
	public void drive(){
		System.out.println("The car started.);
	}
}
//Bus
public class Bus implements Auto{
	@Override
	public void drive(){
		System.out.println("The bus started.);
	}
}

Starting with "plant building", we implemented a simple factory class:

public class AutoFactory{
	//produce ears
	public Auto produce(String name){
		if("car".equals(name)){
			return new Car();
		} else if("bus".equals(name)){
			return new Bus();
		}
	}
}

Everything's ready. We're starting to make cars. Sir, we're making a car.

AutoFactory factory = new AutoFactory();
Auto car = factory.produce("car");
car.drive();

Simple factory mode separates the code for generating product class from the specific product implementation. You can add the logic code for generating product in the factory class, but the problem arises. This does not conform to the principle of "open-closed". That is to say, open to extension and close to modification. If you want to add a new car type, you need to modify the production method to solve the problem. A problem led to the introduction of Factory Method Patterns.

Factory Method Pattern

In order to expand the market, the factory is now starting to produce trucks, so we design a Truck:

//Truck
public class Truck implements Auto{
	@Override
	public void drive(){
		System.out.println("The truck started.);
	}
}

What if, according to the logic of a simple factory, we need to modify the production method (that is, we need to transform the existing factory), which will affect the existing production? The solution is to build new factories:

First we "design" a factory prototype (factory interface):

public interface IAutoFactory{
	//produce ears
	public Auto produce(String name);
}

Then the original factory is simply reconstructed to conform to the designed factory prototype (the interface can be implemented, all logic remains unchanged):

public class AutoFactory implements IAutoFactory{
	//produce ears
	@Override
	public Auto produce(String name){
		if("car".equals(name)){
			return new Car();
		} else if("bus".equals(name)){
			return new Bus();
		}
	}
}

Okay. Next, in order to produce trucks, we need to build separate factories for trucks:

public class TruckAutoFactory implements IAutoFactory{
	//Production truck
	@Override
	public Auto produce(String name){
		return new Truck();
	}
}

Starting production of trucks:

AutoFactory factory = new TruckAutoFactory();
Auto car = factory.produce(null);
car.drive();

In the abstract factory here, in order to reduce the cost of transformation, we make minimal modifications on the basis of simple factories. In theory, the production parameters can not be obtained. Then we build factories for cars, buses and trucks, and produce them separately. In this way, if you have a new type of car, you can build a new "factory" without changing the previous code, so as to achieve the "open and closed principle".

Although it seems that classes have become more and logic is more complex, the benefits of this transformation are also obvious: unchanged old code, through the new factory class to complete the addition of new functions, unchanged old functions, to maximize the avoidance of moving the logic of old code leading to the introduction of new bug s.

The structure diagram of the factory method is as follows:

Abstract Factory Pattern

We continue to explain for the automobile factory, because the factory needs to continue to expand the scale, began to dabble in automotive accessories, the upper level decided to dabble in automotive headlights business, for the production of headlights for existing models. But if we follow the factory method, we need to continue to build a new batch of factories. For each vehicle, we need to rebuild N factories. Considering the cost and simplicity, we need to rebuild the existing automobile factories.

Firstly, "Design" headlamp prototype:

//The headlamps
public interface Light {
	//turn on the light
	public void turnOn();
}

Then "design" car headlights:

//Car headlights
public class CarLight implements Light{
	@Override
	public void tunOn(){
		System.out.println("The car headlights are on.);
	}
}

Then "design" bus headlights:

//Bus headlights
public class BusLight implements Light{
	@Override
	public void tunOn(){
		System.out.println("The bus headlights are on.);
	}
}
//Truck headlights
public class TruckLight implements Light{
	@Override
	public void tunOn(){
		System.out.println("The truck headlights are on.);
	}
}

Next we redesign the original automobile factory (modifying the factory interface or abstract factory class)

public interface IAutoFactory{
	//produce ears
	public Auto produce();
	//Production headlight
	public Light produceLight();
}

Okay, to transform factories, first of all to transform car factories:

public class CarAutoFactory implements IAutoFactory{
	//produce ears
	@Override
	public Auto produce(){
		return new Car();
	}

	//Production of car lights
	@Override
	public Light produceLight(){
		return new CarLight();
	}
}

Renovation of bus factories:

public class BusAutoFactory implements IAutoFactory{
	//produce ears
	@Override
	public Auto produce(){
		return new Bus();
	}

	//Production of car lights
	@Override
	public Light produceLight(){
		return new BusLight();
	}
}

Revamping truck factories:

public class TruckAutoFactory implements IAutoFactory{
	//produce ears
	@Override
	public Auto produce(){
		return new Truck();
	}

	//Production of car lights
	@Override
	public Light produceLight(){
		return new TruckLight();
	}
}

Start production:

AutoFactory factory = new CarAutoFactory();
Auto car = factory.produce();
car.drive();
Light light = factory.produceLight();
light.turnOn();
AutoFactory factory = new BusAutoFactory();
Auto bus = factory.produce();
bus.drive();
Light light = factory.produceLight();
light.turnOn();
AutoFactory factory = new TruckAutoFactory();
Auto truck = factory.produce();
truck.drive();
Light light = factory.produceLight();
light.turnOn();

In the abstract factory model, we can define more than one interface to implement, and more than one product class can be generated by one factory. The abstract factory model better implements the principle of "open-closed", which is more abstract and general among the three models.

The schematic diagram of abstract factory pattern is as follows:

Reference material

Keywords: Java

Added by stbalaji2u on Fri, 17 May 2019 15:01:53 +0300