设计模式之抽象工厂模式:最复杂的工厂模式变种

1. 介绍

抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂。

抽象工厂模式提供了一种创建一系列相关或相互依赖对象的接口,而无需指定具体实现类。通过使用抽象工厂模式,可以将客户端与具体产品的创建过程解耦,使得客户端可以通过工厂接口来创建一族产品。

现实生活中,很少有单一的产品,很多都是各类产品组合,抽象工厂适合解决创建各种产品组合的问题,让代码扩展性更好,更方便维护,方便阅读代码。

1.1 优缺点及建议
  • 优点

    • 确保同一产品族的对象一起工作。

    • 客户端不需要知道每个对象的具体类,简化了代码。

  • 缺点

    • 扩展产品族非常困难。增加一个新的产品族需要修改抽象工厂和所有具体工厂的代码。

2. 实现及相关代码

假设某业务需要创建多类产品,可能会有不同的组合。

2.1 没使用设计模式方式

2.1.1 接口及数据对象
java 复制代码
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的功能逻辑");
    }
}
2.1.2 调用方法
java 复制代码
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();
}
2.1.3 可能会遇到的问题

调整产品组合的这个行为,如果你手动创建产品组合的代码,假如有100个地方,A1+B1

一旦要调整,就是要对100个地方的代码,手动一点一点的去修改,组合的逻辑

这样的代码不可维护,不可扩展,而且阅读性极差

2.2 使用设计模式方式

使用抽象工厂模式,可以把创建对象组合的逻辑都封装到抽象工厂中,当更换产品组合时,只需要调整抽象工厂的产品组合创建即可,外部调用都不需要改变。

代码看起来会很整洁,并且条理清晰,方便阅读和更改。

2.2.1 接口及数据对象
java 复制代码
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();
    }
}
2.2.2 调用方法
java 复制代码
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();
}
相关推荐
guodingdingh2 小时前
软件开发工作问题总结0718
java·开发语言·数据库
咖啡八杯4 小时前
GoF设计模式——解释器模式
java·后端·spring·设计模式
优橙教育4 小时前
5G网优培训 vs Java开发:转行选哪个?
java·开发语言·5g
糖果店的幽灵4 小时前
【DeepAgents 从入门到精通】Context Management 上下文管理
java·人工智能·后端·spring·中间件·langgraph·deepagents
腻害兔6 小时前
【若依项目-产品经理视角】RuoYi-Vue-Pro 源码拆解:字典、短信、邮件、通知——后台系统的“基础设施四件套“!
java·前端·vue.js·产品经理·ai编程
碎光拾影6 小时前
ARM交叉工具链各工具作用及IMX6ULL平台LED+蜂鸣器裸机程序实现
java·开发语言·数据库
大数据新鸟7 小时前
设计模式四大基本原则
设计模式
Miao121317 小时前
微服务 API 测试实践:海外某民宿平台如何构建模式驱动测试基础设施
java·开发语言
腻害兔7 小时前
【若依项目-产品经理视角】RuoYi-Vue-Pro 源码拆解:支付模块 yudao-module-pay,一个让产品经理都看懂的支付中台设计
java·前端·vue.js·产品经理·ai编程
CRMEB系统商城8 小时前
开源自建还是SaaS订阅?算一笔3年经济账
java·大数据·开发语言·开源