preface
The singleton pattern and the constructor pattern were introduced respectively. In practice, these two patterns are highly used. Another highly used design pattern is the factory pattern. Today to understand the factory model, the factory model is a kind of founder model, and the factory model itself is divided into three kinds:
- Simple Factory model
- Factory method pattern
- Abstract Factory pattern
1. Simple factory model
The simple factory pattern is more of a development habit, such as providing a static method in a class that returns a specific object depending on the different parameters passed in.
Take mobile payment as an example.
Abstract payment function:
public interface IPay {
void pay(Double money);
}
Copy the code
To implement ApplePay and HuaWeiPay:
public class ApplePay implements IPay {
@Override
public void pay(Double money) {
System.out.println("Paid with ApplePay." + money + "Yuan"); }}public class HuaWeiPay implements IPay {
@Override
public void pay(Double money) {
System.out.println("Paid with HuaWeiPay" + money + "Yuan"); }}Copy the code
Factory to obtain payment method:
public class PayFactory {
public static IPay getPay(String pay) {
switch (pay) {
case "huawei":
return new HuaWeiPay();
case "apple":
return new ApplePay();
default:
return newApplePay(); }}}Copy the code
The test class:
public class PayMain {
public static void main(String[] args) {
IPay pay = PayFactory.getPay("apple");
pay.pay(1000d);
pay = PayFactory.getPay("huawei");
pay.pay(5000d); }}Copy the code
Results:
As you can see, a static method is provided in the payment factory, which returns a different payment object depending on the payment type passed in to complete the final payment operation. This is the simple factory mode. Let’s look at the factory method mode.
Second, factory method mode
In the factory method pattern, we do away with PayFactory, which creates objects all together. Instead, we provide an abstraction for creating objects, and we delegate specific creation tasks to specific factories, such as getting apple Pay objects, using ApplePayFactory, The HuaWeiPayFactory is used to obtain Huawei Pay
As an example, get the payment object above: Make the following changes:
Change PayFactory to:
public interface PayFactory {
IPay create(a);
}
Copy the code
Create ApplePayFactory and HuaWeiPayFactory to create payment objects respectively:
public class ApplePayFactory implements PayFactory {
@Override
public IPay create(a) {
return newApplePay(); }}public class HuaWeiPayFactory implements PayFactory {
@Override
public IPay create(a) {
return newHuaWeiPay(); }}Copy the code
Testing:
public class MethodFactoryMain {
public static void main(String[] args) {
IPay pay ;
HuaWeiPayFactory huaWeiPayFactory = new HuaWeiPayFactory();
pay = huaWeiPayFactory.create();
pay.pay(1000d);
ApplePayFactory applePayFactory = new ApplePayFactory();
pay = applePayFactory.create();
pay.pay(5000d); }}Copy the code
Results:
It can be seen that the main difference from simple factories is that instead of putting all the creation payment methods in one factory class, a unified definition of a factory to obtain payment methods, and then build different factories by different payment Pay, such as Huawei Pay factory, Apple Pay factory.
In simple factory mode, if we want to add an Oppo payment, we need to change the PayFactory class to add a type judgment, so that if it is not conducive to the expansion and stability of the project code,
In the factory method, we only need to define a factory to get the payment object, and let different manufacturers define their own payment factories, so that even if we add an Oppo payment, we only need to create OppoPay and OppoPayFactory, without changing the top-level abstraction:
public class OppoPay implements IPay {
@Override
public void pay(Double money) {
System.out.println("Paid with OppoPay" + money + "Yuan"); }}public class OppoPayFactory implements PayFactory {
@Override
public IPay create(a) {
return newOppoPay(); }}public class MethodFactoryMain {
public static void main(String[] args) {
IPay pay;
HuaWeiPayFactory huaWeiPayFactory = new HuaWeiPayFactory();
pay = huaWeiPayFactory.create();
pay.pay(1000d);
ApplePayFactory applePayFactory = new ApplePayFactory();
pay = applePayFactory.create();
pay.pay(5000d);
OppoPayFactory oppoPayFactory = new OppoPayFactory();
pay = oppoPayFactory.create();
pay.pay(7000d); }}Copy the code
Results:
As you can see, the factory method pattern scales well without affecting the original code.
Let’s look at the abstract factory pattern
Abstract factory model
The abstract factory pattern is roughly divided into four parts:
-
AbstractFactory AbstractFactory, which declares a set of methods for creating objects
-
The concrete implementation of the ConcreteFactory factory, which implements the methods declared in the abstract factory to create objects, generates a set of objects
-
AbstractProduct AbstractProduct that declares an interface for each object in which the business methods that the object has are declared
-
ConceteeProduct The specific product, which defines what the factory is to achieve.
Let’s take payment as an example.
We know that on different mobile platforms, there are different payment methods, such as
There are payment methods for iPhone: ApplyPay, Alipay, wechat Pay and so on
HuaWei mobile phone has payment methods: HuaWeiPay, Alipay, wechat pay and so on
There are two general categories:
- Mobile payment (various mobile phone Pay)
- Software payment (Alipay, wechat, etc.)
Create abstract products: mobile payment interface and software payment interface:
public interface IPhonePay {
void pay(Double money);
}
public interface ISoftPay {
void pay(Double money);
}
Copy the code
Create an abstract factory:
public interface IPayFactory {
IPhonePay createPhonePay(a);
ISoftPay createSoftPay(a);
}
Copy the code
Implementation of mobile payment interface by Apple and Huawei respectively:
public class ApplyPay implements IPhonePay {
@Override
public void pay(Double money) {
System.out.println("IPhone uses mobile payment." + money + "Yuan"); }}public class HuaWeiPay implements IPhonePay {
@Override
public void pay(Double money) {
System.out.println("Huawei phone uses mobile payment" + money + "Yuan"); }}Copy the code
Implementation of software payment interface by Apple and Huawei respectively:
public class AppleSoftPay implements ISoftPay {
@Override
public void pay(Double money) {
System.out.println("IPhone paid with app (Alipay/wechat)" + money + "Yuan"); }}public class HuaWeiSoftPay implements ISoftPay {
@Override
public void pay(Double money) {
System.out.println("Huawei phone paid with software (Alipay/wechat)" + money + "Yuan"); }}Copy the code
The realization of payment method by Apple mobile phone and Huawei, and the concrete realization of abstract factory:
public class ApplyPayFactory implements IPayFactory {
@Override
public IPhonePay createPhonePay(a) {
return new ApplyPay();
}
@Override
public ISoftPay createSoftPay(a) {
return newAppleSoftPay(); }}public class HuaWeuPayFactory implements IPayFactory {
@Override
public IPhonePay createPhonePay(a) {
return new HuaWeiPay();
}
@Override
public ISoftPay createSoftPay(a) {
return newHuaWeiSoftPay(); }}Copy the code
The test class:
public class Main {
public static void main(String[] args) {
IPayFactory payFactory;
payFactory = new ApplyPayFactory();
payFactory.createPhonePay().pay(1000d);
payFactory.createSoftPay().pay(2000d);
payFactory = new HuaWeuPayFactory();
payFactory.createPhonePay().pay(3000d);
payFactory.createSoftPay().pay(4000d); }}Copy the code
Results:
It can be seen that in the final use, we only need to create payment factories for apple phones and Huawei phones respectively, and then we can use various payment functions of different phones. If Oppo comes along at this time, We can create OppoPhonePay, OppoSoftPay, OppoPayFactory separately.
In fact, the comparison with the above factory method can be roughly seen:
The factory method pattern is a factory for methods
The abstract factory pattern is a factory for objects
So much for the factory model, which needs to be carefully studied at work.