23 Design Pattern Notes The third simple factory pattern, factory method pattern and abstract factory pattern (refer to Mad God video)

content

factory pattern

Simple Factory Pattern (Static Factory Pattern) Simple Factory

 Factory Method Pattern Factory Method

Abstract Factory Pattern

summary


factory pattern

Function : It realizes the separation of creator and caller and helps us instantiate objects.

Core essence : instantiate objects with factories instead of new operations

                  We will select the implementation class and create objects for unified management and control, thereby decoupling the caller from our implementation class

                  Factory pattern is a typical decoupling pattern

Satisfy the seven principles of OOP:

                open-closed principle

                Dependency Inversion Principle

                Law of Demeter (weigh it well)

Classification:

        Simple factory pattern: used to generate any product in the same hierarchical structure (for new products added, existing code needs to be extended).

        Factory method pattern: used to generate fixed products in the same hierarchical structure (supports adding any product).

        Abstract Factory Pattern: Create other factories around a super factory.

Applicable scenarios : As a class creation pattern, the factory method pattern can be used anywhere complex objects need to be generated. One thing to note is that complex objects are suitable for using the factory pattern, while simple objects, especially objects that can be created only by new , do not need to use the factory pattern. When the system needs to have better scalability, the factory mode can be considered, and different products are assembled with different implementation factories.

In fact, the Creational Pattern abstracts the instantiation process of a class and can separate the creation and use of objects in software modules .

The creational pattern provides the software designer with as much flexibility as possible in terms of what to create (What) , who creates it (Who) , and when to create it (When) .

Simple Factory Pattern (Static Factory Pattern) Simple Factory

It is to create a factory class to create instances of some classes that implement the same interface.

The roles in the simple factory pattern are: factory, product, client. See the following example:

First we can look at the class diagram

 The specific implementation code is as follows:

Create a Car interface

public interface Car {
	public void name();
}

Write two implementation classes

public class WuLing implements Car{
	@Override
	public void name() {
		System.out.println("五菱宏光"); 
	}
}

public class Tesla implements Car{
	@Override
	public void name() {
		 System.out.println("特斯拉");
	}  
}

Create a factory class

public class CarFactory{
	public static Car getCar(String car) {
		if(car.equals("五菱")) {
			return new WuLing();
		}else if(car.equals("特斯拉")) {
			return new Tesla();
		}else {
			return null;
		}
	}
}

have a test

public class Comsumer {
	public static void main(String[] args){
		Car car1 = CarFactory.getCar("五菱");
		Car car2 = CarFactory.getCar("特斯拉");
		car1.name();
		car2.name();
	}
}

The result of the output:

 

I don't need to worry about how the car came to be, I just need to provide a name and take it from the factory.

We can clearly feel the drawbacks of this mode. If we now want to add an implementation class of the Car interface and add a Volkswagen car, we must modify the getCar() method in the factory, which violates the open-closed principle. .

Of course, we can modify the methods in the factory class and get what we need without us having to enter parameters.

public class CarFactory{
	public static Car getWuLing(){
        return new WuLing();
	}
    public static Car getTesla(){
        return new Tesla();
	}
}

In fact, this does not meet our needs. We still need to modify the code, but it will not be modified in the code logic like the previous method.

Problems with the simple factory pattern:

                violates the open-closed principle

                Violating the principle of high cohesion responsibility distribution, all the creation logic is centralized into one factory class

 Factory Method Pattern Factory Method

The factory method pattern is a further decoupling of the simple factory pattern, which is equivalent to splitting the simple factory class that would have been huge due to business code into individual factory classes, so that the code will not be coupled to the same class. in.

Although the factory method pattern and the simple factory pattern both create objects through factories, the biggest difference between them is that the factory method pattern is completely in line with the " open-closed principle " in design.

Just look at the example:

 The specific code is implemented as follows:

Car interface, Tesla class and WuLing class remain unchanged

Create car factory interface

public interface CarFactory{
    public Car getCar();
}

Create the implementation class TeslaFactory factory class and WuLingFactory class of the car factory interface

public class TeslaFactory implements CarFactory{
    @Override
    public Car getCar(){
        return new Tesla();
    }
}

public class WuLingFactory implements CarFactory{
    @Override
    public Car getCar(){
        return new WuLing();
    }
}

final test

public class Comsumer {
	public static void main(String[] args){
		Car car1 = new WuLingFactory.getCar();
		Car car2 = new TeslaFactory.getCar();
		car1.name();
		car2.name();
	}
}

Since the example given here does not involve the problem of parameters, our feeling is not very obvious. Just imagine, what if there are many parameters in the Tesla class or WuLing class? This method is friendly to consumers, we don't need to care how the car is made, its corresponding factory method will instantiate it, we just need to call the method in the factory.

Here I think the flow chart of the mad god may be clearer (add layer)

The factory method pattern can be used in the following situations:

        A class does not know the class of the objects it needs.

        A class specifies which object to create through its subclasses

advantage:

        A caller who wants to create an object only needs to know its name.

        High scalability, if you want to add a product, you only need to extend a factory class.

        The specific implementation of the product is shielded, and the caller only cares about the interface of the product.

shortcoming:

        Each time a product is added, a concrete class and object implementation factory need to be added, which doubles the number of classes in the system, increases the complexity of the system to a certain extent, and also increases the dependency of the system's concrete classes. This is not a good thing.

Abstract Factory Pattern

The abstract factory pattern is relative to the factory method pattern, that is, the factory method pattern is for one product series, while the abstract factory pattern is for multiple product series.

Definition : The abstract factory pattern provides an interface to create a series of related or interdependent objects without specifying their concrete classes. The abstract factory pattern is a factory of factories

I personally think it means adding another layer, of course, this is just my personal opinion.

Before telling the case, we need to know the two concepts of product family and product level:

Now let's look at a specific case:

 

First create the phone interface and router interface

//手机产品接口
public interface IPhoneProduct {
	void start();
	void shutdown();
	void callup();
	void sendSMS();
}
//路由器产品接口
public interface IRouterProduct {
	void start();
	void shutdown();
	void openWifi();
	void setting();
}

Then create two implementation classes of mobile phone interfaces: Xiaomi mobile phone and Huawei mobile phone

//小米手机
public class XiaoMiPhone implements IPhoneProduct{

	@Override
	public void start() {
		System.out.println("开启小米手机");
	}

	@Override
	public void shutdown() {
		System.out.println("关闭小米手机");
	}

	@Override
	public void callup() {
		System.out.println("小米手机打电话");
		
	}

	@Override
	public void sendSMS() {
		System.out.println("小米手机发短信");
		
	}

}
//华为手机
public class HuaWeiPhone implements IPhoneProduct{

	@Override
	public void start() {
		System.out.println("开启华为手机");
	}

	@Override
	public void shutdown() {
		System.out.println("关闭华为手机");
	}

	@Override
	public void callup() {
		System.out.println("华为手机打电话");
		
	}

	@Override
	public void sendSMS() {
		System.out.println("华为手机发短信");
		
	}

}

Create implementation classes for two router interfaces: Xiaomi router and Huawei router

//小米路由器
public class XiaoMiRouter implements IRouterProduct {

	@Override
	public void start() {
		System.out.println("启动小米路由器");
	}

	@Override
	public void shutdown() {
		System.out.println("关闭小米路由器");
		
	}

	@Override
	public void openWifi() {
		System.out.println("小米路由器打开WiFi");
	}

	@Override
	public void setting() {
		System.out.println("小米路由器设置");
	}

}
//华为路由器
public class HuaWeiRouter implements IRouterProduct {

	@Override
	public void start() {
		System.out.println("启动华为路由器");
	}

	@Override
	public void shutdown() {
		System.out.println("关闭华为路由器");
		
	}

	@Override
	public void openWifi() {
		System.out.println("华为路由器打开WiFi");
	}

	@Override
	public void setting() {
		System.out.println("华为路由器设置");
	}

}

Write an abstract product factory to manufacture

//抽象产品工厂
public interface IProductFactory {	
	//生产手机
	IPhoneProduct iphoneProduct();
	//生产路由器
	IRouterProduct irouterProduct();
}

Create an implementation class for an abstract product factory

//小米工厂
public class XiaoMiFactory implements IProductFactory {

	@Override
	public IPhoneProduct iphoneProduct() {
		return new XiaoMiPhone();
	}

	@Override
	public IRouterProduct irouterProduct() {
		return new XiaoMiRouter();
	}
}
//华为工厂
public class HuaWeiFactory implements IProductFactory {

	@Override
	public IPhoneProduct iphoneProduct() {
		return new HuaWeiPhone();
	}

	@Override
	public IRouterProduct irouterProduct() {
		return new HuaWeiRouter();
	}

}

Write a client test:

public class Client {
	public static void main(String[] args) {
		System.out.println("**********华为系列***********");
		//华为工厂
		HuaWeiFactory huaweiFactory = new HuaWeiFactory();
		IPhoneProduct huaweiPhone = huaweiFactory.iphoneProduct();
		huaweiPhone.start();
		huaweiPhone.callup();
	}
}

operation result:

Applicable scenarios: The client (application layer) does not depend on the details of how the product class instance is created and implemented. Emphasizes that a series of related product objects (belonging to the same product family) are used together to create objects that require a lot of repetitive code to provide a library of product classes, all products appearing with the same interface, so that the client does not depend on the specific implementation

advantage:

        Code isolation of specific products at the application layer, no need to care about the details of creation

        Create a family of products together

shortcoming:

        Specifies all possible product sets that can be created, and the difficulty of expanding new products in the product family;

        Increases the abstraction and difficulty of understanding the system

summary

Simple Factory Pattern: Although it does not conform to the design principles to some extent, it is actually used the most

Factory Method Pattern: Extend by adding new factory classes without modifying existing classes

Abstract Factory Pattern: You cannot add products, you can add product families

(Joke: There is nothing that can’t be solved by adding a layer)

At the end of the study, we must know one thing clearly, that is, don’t put the cart before the horse. We learn design patterns to design software better, not to design for the use of a certain design pattern.

Guess you like

Origin blog.csdn.net/qq_44709970/article/details/124374065