【Java设计模式 | 创建者模式】 抽象工厂模式

前言:

创建者模式主要关注是"怎么创建对象?",它的主要特点是将对象的创建和使用分离。这样可以降低系统的耦合度,使用者不需要关注对象的创建细节。

创建者模式分为:

单例模式(Singleton):【Java设计模式 | 创建者模式】单例模式-CSDN博客

工厂方法模式(Factory Method):【Java设计模式 | 创建者模式】工厂方法模式-CSDN博客

抽象工厂模式(Abstract Factory):【Java设计模式 | 创建者模式】 抽象工厂模式-CSDN博客

建造者模式(Builder)

原型模式(Prototype)

前面所说的工厂方法模式中考虑的是一类产品的生产,例如畜牧场只养动物、冰箱厂只造冰箱。

这些工厂只生产同种类产品,同种类产品又称同级别产品,也就是说:工厂方法模式只考虑生产同等级的产品,但在现实生活中,有很多综合类的工厂,能生产多等级产品,例如家电厂不只造冰箱,还造微波炉,空调等。

本文要介绍的抽象工厂模式就是考虑了多等级的生产(产品族),将同一个工厂所生产的位于不同等级的一组产品称为一个产品族。

如下图,下面的六个产品都是一个工厂制造。第一列都是不同的电脑,称为同级别产品;第二行为一个电脑,一个手机,显然不是同级别产品,但它们是同一个工厂创造出来的,我们将它们称为一个产品族。

抽象工厂模式:

概念:

是一种为访问类提供一个创建一组相关的或相互依赖对象的接口,且访问类无需指定所要产品的具体类就能的得到同族的不同等级的产品的模式结构。

例如你说你想要华为全家桶,抽象工厂就会自动给你生产华为电脑,华为手机,华为平板这一产品族。

结构:

抽象工厂模式的主要角色如下:

抽象工厂(Abstract Factory):提供了创建产品的接口,它包含了多个创建产品的方法,可以创建多个等级的产品

具体工厂(ConcreteFactory):主要是实现抽象工厂中的多种抽象方法,完成了具体产品的创建。

抽象产品接口(Abstract Product):定义了产品的规范,描述了产品的主要特性和功能。

具体产品(ConcreteProduct):实现了抽象产品角色所定义的接口,由具体工厂来创建。它同具体工厂之间是多对一对应。

实现:

抽象产品接口:定义两种抽象产品:Button 和 Checkbox。

java 复制代码
public interface Button {
    void render();
}

public interface Checkbox {
    void render();
}
 

具体产品实现:创建两套具体产品:Windows 风格和 MacOS 风格。

java 复制代码
// Windows风格产品
public class WindowsButton implements Button {
    @Override
    public void render() {
        System.out.println("Render a Windows style button");
    }
}

public class WindowsCheckbox implements Checkbox {
    @Override
    public void render() {
        System.out.println("Render a Windows style checkbox");
    }
}

// MacOS风格产品
public class MacOSButton implements Button {
    @Override
    public void render() {
        System.out.println("Render a MacOS style button");
    }
}

public class MacOSCheckbox implements Checkbox {
    @Override
    public void render() {
        System.out.println("Render a MacOS style checkbox");
    }
}
 

抽象工厂接口:定义工厂接口,包含创建产品族的方法。

java 复制代码
public interface GUIFactory {
    Button createButton();
    Checkbox createCheckbox();
}
 

具体工厂实现:实现针对不同操作系统的工厂。

java 复制代码
// Windows工厂
public class WindowsFactory implements GUIFactory {
    @Override
    public Button createButton() {
        return new WindowsButton();
    }

    @Override
    public Checkbox createCheckbox() {
        return new WindowsCheckbox();
    }
}

// MacOS工厂
public class MacOSFactory implements GUIFactory {
    @Override
    public Button createButton() {
        return new MacOSButton();
    }

    @Override
    public Checkbox createCheckbox() {
        return new MacOSCheckbox();
    }
}
 

测试代码:通过抽象工厂创建产品族,无需关心具体实现。

java 复制代码
public class Application {
    private Button button;
    private Checkbox checkbox;

    public Application(GUIFactory factory) {
        button = factory.createButton();
        checkbox = factory.createCheckbox();
    }

    public void render() {
        button.render();
        checkbox.render();
    }
}

// 使用示例
public class Demo {
    public static void main(String[] args) {
        // 创建Windows风格应用
        Application winApp = new Application(new WindowsFactory());
        winApp.render();

        // 创建MacOS风格应用
        Application macApp = new Application(new MacOSFactory());
        macApp.render();
    }
}
 

运行结果示例:执行Demo类后输出:

css 复制代码
Render a Windows style button
Render a Windows style checkbox
Render a MacOS style button
Render a MacOS style checkbox
 

优点:

当一个产品族中的多个对象被设计在一起工作时,它能保证客户端始终只使用同一个产品族的对象。

例如:用MacOS工厂,只会生成Mac按钮+Mac复选框,绝对不会出现「Mac按钮+Windows复选框」的混乱界面。

缺点:

当某一个产品族中需要添加一个新的产品时,所有相关的工厂类都需要去修改。

例如:如果要加一个新的产品等级「输入框(input)」,就必须修改抽象工厂接口,并且MacOS、Windows等所有具体工厂都要新增 createInput() 方法,代码改动量大。

总结:

抽象工厂模式对于开闭原则的遵守有一定界限,也就是说如果你去添加一个新的产品族不违背,但要是在某一个产品族里添加新的产品就违背了。

相关推荐
计算机毕设定制辅导-无忧学长21 分钟前
《基于微信小程序的居家医疗陪护预约系统设计与实现》
java·spring boot·微信小程序·uniapp·居家医疗陪护预约系统
张张123y35 分钟前
DSH 插件调试避坑:client.js 设置面板、热重载与高频报错排查表
开发语言·javascript·人工智能·开源·ecmascript·后端开发·ai agent
文丑颜不良啊2 小时前
LeetCode2221~2240题目解析
java·leetcode
秋饼2 小时前
Computer Use Agent Java 落地实战:感知-行动循环、执行器与安全围栏生产级实现
java·ai·技术分享·后端开发
wo_jack2 小时前
C++ 入门笔记(十六):第16课 vector 模拟实现十问十答 —— 从三指针到迭代器失效
c++·后端·面试·stl·vector
量化分析码农3 小时前
【Python量化波动率实战 02】波动率会传染:EWMA 指数加权给近期行情更大话语权
后端
冻柠檬飞冰走茶3 小时前
字母移动游戏题解:贪心求最长可保留连续子串(附 C 实现)
c语言·开发语言·数据结构·算法·动态规划
心若自由何处是束缚4 小时前
适配器模式:从原理到实战的完整指南
设计模式·适配器模式
文丑颜不良啊4 小时前
LeetCode2161~2180题目解析
java·leetcode
FRing034 小时前
vue2干货总结7(自定义指令、插槽、单页应用程序、路由的使用(VueRouter))
开发语言·前端·vue.js·vue2