抽象工厂模式

1. 模式动机

  • 在工厂方法模式中具体工厂负责生产具体的产品,每一个具体工厂对应一种具体的产品,工厂方法也具有唯一性,一般情况下,一个具体工厂中只有一个工厂方法或者一组重载的工厂方法。但是有时候我们需要一个工厂可以提供多个产品对象,而不是单一的产品对象。
    为了更清晰的理解工厂方法模式,需要先引入两个概念:
    • 产品等级结构:即产品的继承结构,如一个抽象类是CPU,其子类有interCpu、AMDCpu等,则抽象Cpu和具体品牌的Cpu之间构成了一个产品等级结构,抽象Cpu是父类,或接口,而具体品牌的Cpu是其子类或继承。
    • 产品族:在抽象工厂模式中,产品族是指由同一个工厂生产的,位于不同产品等级结构中的一组产品,如InterCpu,Inter显卡,Inter主板等。
      抽象工厂模式_第1张图片
      image.png
  • 当系统所提供的工厂所需生产的具体产品并不是一个简单的对象,而是多个位于不同产品等级结构中属于不同类型的具体产品时需要使用抽象工厂模式。
  • 抽象工厂模式是所有形式的工厂模式中最为抽象和最具一般性的一种形态。
  • 抽象工厂模式与工厂方法模式最大的却别在于,工厂方法模式针对的是一个产品等级结构,而抽象工厂模式则需要面对多个产品等级结构,一个工厂等级结构可以负责多个不同产品等级结构中的产品对象的创建。当一个工厂等级结构可以创建出属于不同产品等级结构的一个产品族中的所有对象时,抽象工厂模式比工厂方法模式更为简单、有效率。

2. 模式定义

抽象工厂模式(Abstract Factory Pattern): 提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。抽象工厂模式又成为Kit模式,属于对象创见性模式。

模式结构

抽象工厂模式包含如下角色

  • AbstractFactory: 抽象工厂角色
  • ConcreateFactory: 具体工厂角色
  • AbstractProduct: 抽象产品角色
  • ConcreateFactory: 具体产品角色


    抽象工厂模式_第2张图片
    image

3. 时序图

抽象工厂模式_第3张图片
image

4. 代码分析

/**
 * 抽象产品
 */
public interface Cpu {
    void create();
}
public class AmdCpu implements Cpu {

    private String name = "英伟达CPU";

    private int cpuHoles; //针脚数

    AmdCpu(int cpuHoles){
        this.cpuHoles = cpuHoles;
    }

    @Override
    public void create() {
        System.out.println(name + "针脚数: " + cpuHoles);
    }
}
public class IntelCpu implements Cpu {

    IntelCpu(int cpuHoles){
        this.cpuHoles = cpuHoles;
    }

    private String name = "英特尔CPU";

    private int cpuHoles;//针脚数

    @Override
    public void create() {
        System.out.println(name + "针脚数: " + cpuHoles);
    }
}
/**
 * 主板接口
 */
public interface Mainboard {
    void show();
}
public class AmdMainboard implements Mainboard {

    private String name = "英伟达主板";

    private int holes;//针脚数

    AmdMainboard(int holes){
        this.holes = holes;
    }

    @Override
    public void show() {
        System.out.println(name + "针脚数: " + holes);
    }
}
public class IntelMainboard implements Mainboard {
    private String name = "英特尔主板";

    private int holes;//针脚数

    @Override
    public void show() {
        System.out.println(name + "针脚数: " + holes);
    }

    IntelMainboard(int holes){
        this.holes = holes;
    }
}
/**
 * 抽象工厂
 */
public interface AbstractFactory {
    Cpu getCpu();
    Mainboard getMainboard();
}
public class AmdFactory implements AbstractFactory {
    @Override
    public Cpu getCpu() {
        return new AmdCpu(755);
    }

    @Override
    public Mainboard getMainboard() {
        return new AmdMainboard(755);
    }
}
public class IntelFactory implements AbstractFactory {
    @Override
    public Cpu getCpu() {
        return new IntelCpu(877);
    }

    @Override
    public Mainboard getMainboard() {
        return new IntelMainboard(877);
    }
}
public class MainClass {
    public static void main(String[] args) {
        AbstractFactory factory = new IntelFactory();
        factory.getCpu().create();
        factory.getMainboard().show();
    }
}

5. 抽象工厂的起源

抽象工厂模式的起源或者最早的应用,是用于创建分属于不同操作系统的视窗构建。比如:命令按键(Button)于文字框(Text)都是视窗构建,在UNIX操作系统的视窗环境和Windows操作系统的视窗环境中,这两个构建有不同的本地实现,它们的细节有所不同。
在每一个操作系统中,都有一个视窗构建组成的构建家族在这里就是Button和Text组成的产品族。而每一个视窗构建都构成自己的等级结构,又一个抽象橘色给出抽象的功能描述,而由具体子类给出不同操作系统下的具体实现。


抽象工厂模式_第4张图片
image.png

6. 优点

  • 分离接口和实现:客户端使用抽象工厂来创建的对象,而客户端根本就不知道具体的实现是谁,客户端只是面向产品的接口编程而已。也就是说,客户端从具体的产品实现中解耦。
  • 使切换产品族变得容易:因为一个具体的工厂实现代表的使一个产品族,比如上面例子的从intel系列到AMD系列只需要切换一下具体工厂。

7. 缺点

  • 不抬容易扩展新的产品:如果需要给整个产品族添加一个新的产品,那么就需要修改抽象工厂,这样就会导致修改所有的工厂实现类。

参考:图说设计模式
参考:java_my_life

你可能感兴趣的:(抽象工厂模式)