Factory pattern, abstract factory pattern -- java

Posted by jeff_papciak on Fri, 04 Mar 2022 02:19:48 +0100

Factory mode

effect:

It realizes the separation of creator and caller

Detailed classification:

  • Simple factory mode
    • It is used to produce any product in the same hierarchical structure (for adding new products, the existing code needs to be overwritten)
  • Factory mode method
    • It is used to produce fixed products with the same level structure (any addition is supported)
  • Abstract factory pattern
    • Create other factories around one super factory. The super factory is also known as the factory of other factories

Seven principles of OOP

  • Opening and closing principle: a software entity should be open to expansion and closed to modification
  • Dependency Inversion Principle: program for the interface, not for the implementation
  • Dimitri's Law: only communicate with your direct friends and avoid communicating with strangers

Core essence:

  • The instance object cannot be new, instead of factory mode
  • The implementation class will be selected to create objects for unified management and control. And decouple the caller from our implementation class

Code demonstration:

Simple factory mode (static factory mode):
tip: although it does not conform to the design principles to some extent, it is actually used most

public interface Car {
	public void name();
}
public class WuLingHongGuang implements Car{
	@Override
	public void name() {
		System.out.println("I'm Wuling Hongguang");
	}
}
public class WuLingHongGuang implements Car{
	@Override
	public void name() {
		System.out.println("I'm Wuling Hongguang");
	}
}
//Another name: static factory mode (simple factory mode)
//Disadvantages: add a new product. If you don't modify the code, you can't
//Opening and closing principle
public class CarFactory {
	//Method 1
	//When the third party takes the car, it only needs to pass in String car
	public static Car getCar(String car){
		if (car.equals("Wuling Hongguang")) {
			return new WuLingHongGuang();
		}else if (car.equals("BYD")) {
			return new Byd();
		}else {
			return null;
		}	
	}
	 //Method 2
	public static Car getWuLingHongGuang(){
		return new WuLingHongGuang();
	}
	public static Car getByd(){
		return new Byd();
	}
}
public class Consumer {
	public static void main(String[] args) {
		// 1. Original writing
		//You must know the interface and all the implementation classes
//		Car car = new WuLingHongGuang();
//		Car car2 = new Byd();	
		//2. Create with factory
		Car car = CarFactory.getCar("Wuling Hongguang");
		Car car2 = CarFactory.getCar("BYD");
		car.name();
		car2.name();	
	}
}

Factory mode method:
tip: extend by adding new factory classes without modifying existing classes

public interface Car {
	public void name();
}
//Factory method model
public interface CarFactory {
	Car getCar();
}
public class Byd implements Car{
	@Override
	public void name() {
		System.out.println("I'm BYD");
	}
}
public class BydFactory implements CarFactory{
	@Override
	public Car getCar() {
		return new Byd();
	}
}
public class WuLingHongGuang implements Car{
	@Override
	public void name() {
		System.out.println("I'm Wuling Hongguang");
	}
}
public class WuLingHongGuangFactory implements CarFactory{
	@Override
	public Car getCar() {
		return new WuLingHongGuang();
	}
}
public class MoBai implements Car{
	@Override
	public void name() {
		System.out.println("Mobike");		
	}
}
public class MoBaiFactory implements CarFactory{
	@Override
	public Car getCar() {
		return new MoBai();
	}
}
public class Consumer {
	public static void main(String[] args) {
		Car car = new WuLingHongGuangFactory().getCar();
		Car car2 = new BydFactory().getCar();
		car.name();
		car2.name();
		Car car3 = new MoBaiFactory().getCar();
		car3.name();
	}
}

Summary:

Comparison between simple factory mode and factory method mode:

  1. Structural complexity: simple factory model
  2. Code complexity: simple factory mode
  3. Factory complexity: simple programming mode
  4. Management complexity: simple factory model
  5. According to the design principle: factory method mode (without disturbing the program)
  6. According to the actual business: simple factory mode (most software generally use simple factory mode)

Abstract factory pattern (the essence is different from factory pattern):
Definition: the abstract factory pattern provides an interface to create a series of related or interdependent objects without specifying their specific classes
tip: products cannot be added, but product families can be added
Applicable scenarios:

  • The client (application layer) does not depend on the details of how the product class instance is created and implemented
  • Emphasize that a series of related product objects (belonging to the same product family) are used together. Creating objects requires a lot of duplicate code
  • Provide a library of product classes. All products appear with the same interface, so that the client does not depend on the specific implementation

advantage:

  • The code isolation of specific products in the application layer does not need to care about the details of creation
  • Unify a series of products to create

Disadvantages:

  • All product sets that may be created are specified, and it is difficult to expand new products in the product family
  • It increases the abstraction and understanding difficulty of the system


Code demonstration:

//Mobile product interface
public interface IphoneProduct {
	public void start();
	public void shutdown();
	public void callup();
	public void sendSMS();
}
//Router product interface
public interface IRouterProduct {
	public void start();
	public void shutdown();
	public void openWife();
	public void setting();
}

//Abstract product factory
public interface IProductFactory {
	//Production of mobile phones
	IphoneProduct iphoneProduct();
	//Production router 
	IRouterProduct iRouterProduct();
}

//Huawei Mobile
public class HuaweiPhone implements IphoneProduct{

	@Override
	public void start() {
		System.out.println("Turn on Huawei mobile phone");
		
	}

	@Override
	public void shutdown() {
		System.out.println("Turn off Huawei mobile phone");
		
	}

	@Override
	public void callup() {
		System.out.println("Huawei calls");
	}

	@Override
	public void sendSMS() {
		System.out.println("Huawei sends text messages");
		
	}

}

//Huawei router
public class HuaweiRouter implements IRouterProduct{

	@Override
	public void start() {
		System.out.println("Start Huawei router");
		
	}

	@Override
	public void shutdown() {
		System.out.println("Turn off Huawei router");
		
	}

	@Override
	public void openWife() {
		System.out.println("Call Huawei WiFi");
		
	}

	@Override
	public void setting() {
		System.out.println("Turn off Huawei settings");
		
	}

}

public class HuaweiFactory implements IProductFactory{

	@Override
	public IphoneProduct iphoneProduct() {
		return new HuaweiPhone();
	}

	@Override
	public IRouterProduct iRouterProduct() {
		return new HuaweiRouter();
	}

}
//Mi phones
public class XiaomiPhine implements IphoneProduct{

	@Override
	public void start() {
		System.out.println("Turn on Xiaomi mobile phone");
		
	}

	@Override
	public void shutdown() {
		System.out.println("Turn off Xiaomi mobile phone");
		
	}

	@Override
	public void callup() {
		System.out.println("Xiaomi called");
		
	}

	@Override
	public void sendSMS() {
		System.out.println("Xiaomi sends text messages");
		
	}

}
//Xiaomi router
public class XiaomiRouter implements IRouterProduct{

	@Override
	public void start() {
		System.out.println("Start Xiaomi router");
		
	}

	@Override
	public void shutdown() {
		System.out.println("Turn off Xiaomi router");
		
	}

	@Override
	public void openWife() {
		System.out.println("It's Xiaomi WiFi");
		
	}

	@Override
	public void setting() {
		System.out.println("Turn off Xiaomi settings");
		
	}

}

public class XiaomiFactory implements IProductFactory{

	@Override
	public IphoneProduct iphoneProduct() {
		return new XiaomiPhine();
	}

	@Override
	public IRouterProduct iRouterProduct() {
		return new XiaomiRouter();
	}

}
//Client call
public class Client {
	public static void main(String[] args) {
		System.out.println("=======Xiaomi series products======");
		//Millet factory
		XiaomiFactory xiaomiFactory = new XiaomiFactory();
		IphoneProduct iphoneProduct=xiaomiFactory.iphoneProduct();//Production of Xiaomi mobile phone
		iphoneProduct.callup();
		iphoneProduct.sendSMS();
		iphoneProduct.start();
		iphoneProduct.shutdown();
		IRouterProduct iRouterProduct=xiaomiFactory.iRouterProduct();//Production of Xiaomi router
		iRouterProduct.openWife();
		iRouterProduct.shutdown();
		System.out.println("======Huawei series products======");
		HuaweiFactory huaweiFactory = new HuaweiFactory();
		IphoneProduct iphoneProduct2=huaweiFactory.iphoneProduct();//Production of Huawei mobile phones
		iphoneProduct2.sendSMS();
		iphoneProduct2.shutdown();
		iphoneProduct2.shutdown();
		iphoneProduct2.start();
		IRouterProduct iRouterProduct2 = huaweiFactory.iRouterProduct();//Production of Huawei router
		iRouterProduct2.openWife();
		iRouterProduct2.shutdown();
		iRouterProduct2.setting();
		
	}
}

Output result:

Abstract factory pattern logic summary:

Topics: Java Design Pattern