1. 设计模式之抽象工厂模式:最复杂的工厂模式变种
1.1. 介绍
抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂。
抽象工厂模式提供了一种创建一系列相关或相互依赖对象的接口,而无需指定具体实现类。通过使用抽象工厂模式,可以将客户端与具体产品的创建过程解耦,使得客户端可以通过工厂接口来创建一族产品。
现实生活中,很少有单一的产品,很多都是各类产品组合,抽象工厂适合解决创建各种产品组合的问题,让代码扩展性更好,更方便维护,方便阅读代码。
优缺点及建议
优点
1.确保同一产品族的对象一起工作。
2.客户端不需要知道每个对象的具体类,简化了代码。
缺点
1.扩展产品族非常困难。增加一个新的产品族需要修改抽象工厂和所有具体工厂的代码。
1.2. 实现及相关代码
假设某业务需要创建多类产品,可能会有不同的组合。
1.2.1. 没使用设计模式方式
接口及数据对象
public interface ProductA {
void execute();
}
public static class ProductA1 implements ProductA {
public void execute() {
System.out.println("产品A1的功能逻辑");
}
}
public static class ProductA2 implements ProductA {
public void execute() {
System.out.println("产品A2的功能逻辑");
}
}
public static class ProductA3 implements ProductA {
public void execute() {
System.out.println("产品A3的功能逻辑");
}
}
public interface ProductB {
void execute();
}
public static class ProductB1 implements ProductB {
public void execute() {
System.out.println("产品B1的功能逻辑");
}
}
public static class ProductB2 implements ProductB {
public void execute() {
System.out.println("产品B2的功能逻辑");
}
}
public static class ProductB3 implements ProductB {
public void execute() {
System.out.println("产品B3的功能逻辑");
}
}
调用方法
public static void main(String[] args) {
// 我们现在要创建产品A1+产品B1的组合
// ProductA productA1 = new ProductA1();
// ProductB productB1 = new ProductB1();
//
// productA1.execute();
// productB1.execute();
// 产品A1+产品B1 --变成--> 产品A1+产品B3的组合
ProductA productA1 = new ProductA1();
ProductB otherProductB3 = new ProductB3();
productA1.execute();
otherProductB3.execute();
// 我们现在要创建产品A2+产品B2的组合
ProductA productA2 = new ProductA2();
ProductB productB2 = new ProductB2();
productA2.execute();
productB2.execute();
// 我们现在要创建产品A3+产品B3的组合
ProductA productA3 = new ProductA3();
ProductB productB3 = new ProductB3();
productA3.execute();
productB3.execute();
}
可能会遇到的问题
调整产品组合的这个行为,如果你手动创建产品组合的代码,假如有100个地方,A1+B1
一旦要调整,就是要对100个地方的代码,手动一点一点的去修改,组合的逻辑
这样的代码不可维护,不可扩展,而且阅读性极差
1.2.2. 使用设计模式方式
使用抽象工厂模式,可以把创建对象组合的逻辑都封装到抽象工厂中,当更换产品组合时,只需要调整抽象工厂的产品组合创建即可,外部调用都不需要改变。
代码看起看会很整洁,并且条理清晰,方便阅读和更改。
接口及数据对象
public interface ProductA {
void execute();
}
public static class ProductA1 implements ProductA {
public void execute() {
System.out.println("产品A1的功能逻辑");
}
}
public static class ProductA2 implements ProductA {
public void execute() {
System.out.println("产品A2的功能逻辑");
}
}
public static class ProductA3 implements ProductA {
public void execute() {
System.out.println("产品A3的功能逻辑");
}
}
public interface ProductB {
void execute();
}
public static class ProductB1 implements ProductB {
public void execute() {
System.out.println("产品B1的功能逻辑");
}
}
public static class ProductB2 implements ProductB {
public void execute() {
System.out.println("产品B2的功能逻辑");
}
}
public static class ProductB3 implements ProductB {
public void execute() {
System.out.println("产品B3的功能逻辑");
}
}
public interface Factory {
ProductA createProductA();
ProductB createProductB();
}
public static class Factory1 implements Factory {
private static final Factory1 instance = new Factory1();
private Factory1() {}
public static Factory get() {
return instance;
}
public ProductA createProductA() {
return new ProductA1();
}
public ProductB createProductB() {
// 根据组合形式调整创建对象即可,修改一个地方,所以调用的地方组合一起改动
// return new ProductB1();
return new ProductB3();
}
}
public static class Factory2 implements Factory {
private static final Factory2 instance = new Factory2();
private Factory2() {}
public static Factory get() {
return instance;
}
public ProductA createProductA() {
return new ProductA2();
}
public ProductB createProductB() {
return new ProductB2();
}
}
public static class Factory3 implements Factory {
private static final Factory3 instance = new Factory3();
private Factory3() {}
public static Factory get() {
return instance;
}
public ProductA createProductA() {
return new ProductA3();
}
public ProductB createProductB() {
return new ProductB3();
}
}
调用方法
public static void main(String[] args) {
// 产品A1+产品B1 -> 产品A1+产品B3(只需要在对应工厂方法中,调整组合创建的对象即可)
ProductA firstProductA = Factory1.get().createProductA();
ProductB firstProductB = Factory1.get().createProductB();
firstProductA.execute();
firstProductB.execute();
// 产品A2+产品B2
ProductA secondProductA = Factory2.get().createProductA();
ProductB secondProductB = Factory2.get().createProductB();
secondProductA.execute();
secondProductB.execute();
// 产品A3+产品B3
ProductA thirdProductA = Factory3.get().createProductA();
ProductB thirdProductB = Factory3.get().createProductB();
thirdProductA.execute();
thirdProductB.execute();
}