1 Star 0 Fork 552

Leader / CS-Wiki

forked from 小牛肉 / cs-wiki 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
1-工厂方法模式.md 5.86 KB
一键复制 编辑 原始数据 按行查看 历史
小牛肉 提交于 2021-07-11 21:36 . 🥽 更新目录结构

🌞 工厂方法模式 Factory Method


1. 模式动机

定义了一个创建对象的接口,但由子类决定要实例化哪个类。工厂方法把实例化操作推迟到子类。

例如:现在对 简单工厂模式的按钮系统 进行修改,不再设计一个按钮工厂类来统一负责所有产品的创建,而是将具体按钮的创建过程交给专门的工厂子类去完成

我们先定义一个抽象的按钮工厂类,该抽象类具有有生成按钮的抽象方法(并无方法体),再定义具体的工厂类来生成圆形按钮、矩形按钮、菱形按钮等,它们实现在抽象按钮工厂类中定义的抽象方法。 这种抽象化的结果使这种结构可以在不修改具体工厂类的情况下引进新的产品,如果出现新的按钮类型,只需要为这种新类型的按钮创建一个具体的工厂类就可以获得该新按钮的实例,这一特点无疑使得工厂方法模式具有超越简单工厂模式的优越性,更加符合“开闭原则”。

2. 模式定义

工厂方法模式(Factory Method Pattern)又称为工厂模式,也叫虚拟构造器(Virtual Constructor)模式或者多态工厂(Polymorphic Factory)模式,它属于类创建型模式。

在工厂方法模式中,工厂父类负责定义创建产品对象的公共接口,而工厂子类则负责生成具体的产品对象,这样做的目的是将产品类的实例化操作延迟到工厂子类中完成,即通过工厂子类来确定究竟应该实例化哪一个具体产品类。

💡 在简单工厂中,创建对象的是父类,而在工厂方法中,是由子类来创建对象

3. 模式结构

工厂方法模式包含如下角色:

  • AbstratProduct:抽象产品
  • ConcreteProduct:具体产品
  • AbstractFactory:抽象工厂
  • ConcreteFactory:具体工厂

4. 代码实例

有四个角色,抽象工厂,具体工厂,抽象产品,具体产品。不再是由一个工厂类去实例化具体的产品,而是由抽象工厂的子类去实例化产品

① 抽象产品 Product

定义接口

public interface Bus {

    void run();

    void stop();
}

② 具体产品 ConcreteProduct

实现接口

public class BusImpl1 implements Bus {
    @Override
    public void run() {
        System.out.println("BusImpl1 is running");
    }

    @Override
    public void stop() {
        System.out.println("BusImpl1 stop running");
    }
}
public class BusImpl2 implements Bus {
    @Override
    public void run() {
        System.out.println("BusImpl2 is running");
    }

    @Override
    public void stop() {
        System.out.println("BusImpl2 stop running");
    }
}

③ 抽象工厂 Factory

定义产品生成接口

/**
 * 抽象工厂
 */
public abstract class AbstractFactory {
    abstract public Bus create();
}

④ 具体工厂 ConcreteFactory

实现产品生成接口,生成具体产品角色对象

/**
 * 具体工厂
 */
public class BusImpl1Factory extends AbstractFactory {
    @Override
    public Bus create() {
        return new BusImpl1();
    }
}
/**
 * 具体工厂
 */
public class BusImpl2Factory extends AbstractFactory {
    @Override
    public Bus create() {
        return new BusImpl2();
    }
}

⑤ 客户端

public class Client1 {
    public static void main(String[] args) {
        // 由抽象工厂的子类去实例化产品
        AbstractFactory busImpl1Factory = new BusImpl1Factory();
        Bus busImpl1 = busImpl1Factory.create();
        busImpl1.run();

        AbstractFactory busImpl2Factory = new BusImpl2Factory();
        Bus busImpl2 = busImpl2Factory.create();
        busImpl2.stop();
    }
}

5. 工厂方法模式的应用

应用:某系统日志记录器要求支持多种日志记录方式,如文件记录、数据库记录等,且用户可以根据要求动态选择日志记录方式, 可使用工厂方法模式设计该系统。

6. 分析与总结

  • 工厂方法模式又称为工厂模式,它属于类创建型模式。在工厂方法模式中,工厂父类负责定义创建产品对象的公共接口,而工厂子类则负责生成具体的产品对象,这样做的目的是将产品类的实例化操作延迟到工厂子类中完成,即通过工厂子类来确定究竟应该实例化哪一个具体产品类。

  • 具体工厂负责生产具体的产品,每一个具体工厂对应一种具体产品

  • 工厂方法模式是简单工厂模式的进一步抽象和推广。由于使用了面向对象的多态性,工厂方法模式保持了简单工厂模式的优点,而且克服了它的缺点。

    在工厂方法模式中,核心的工厂类不再负责所有产品的创建,而是将具体创建工作交给子类去做。这个核心类仅仅负责给出具体工厂必须实现的接口,而不负责产品类被实例化这种细节,这使得工厂方法模式可以允许系统在不修改工厂角色的情况下引进新产品

  • 工厂方法模式的主要 优点 是增加新的产品类时无须修改现有系统,并封装了产品对象的创建细节,系统具有良好的灵活性和可扩展性;

    缺点 在于增加新产品的同时需要增加新的工厂,导致系统类的个数成对增加,在一定程度上增加了系统的复杂性。

  • 工厂方法模式适用情况包括:

    • 一个类不知道它所需要的对象的类;

    • 一个类通过其子类来指定创建哪个对象;

    • 将创建对象的任务委托给多个工厂子类中的某一个,客户端在使用时可以无须关心是哪一个工厂子类创建产品子类,需要时再动态指定。

Java
1
https://gitee.com/mmbuy_admin/CS-Wiki.git
git@gitee.com:mmbuy_admin/CS-Wiki.git
mmbuy_admin
CS-Wiki
CS-Wiki
master

搜索帮助