抽象工厂模式

概念

抽象工厂模式(Abstract Factory Pattern)是指提供一个创建一系列相关或相互依赖对象的接口,无须指定他们具体的类。客户端(应用层)不依赖于产品类实例如何被创建、实现等细节,强调的是一系列相关的产品对象(属于同一产品族)一起使用创建对象需要大量重复的代码。需要提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于具体实现。

角色

  • AbstractFactory(抽象工厂):它声明了一组用于创建一族产品的方法,每一个方法对应一种产品。
  • ConcreteFactory(具体工厂):它实现了在抽象工厂中声明的创建产品的方法,生成一组具体产品,这些产品构成了一个产品族,每一个产品都位于某个产品等级结构中。
  • AbstractProduct(抽象产品):它为每种产品声明接口,在抽象产品中声明了产品所具有的业务方法。
  • ConcreteProduct(具体产品):它定义具体工厂生产的具体产品对象,实现抽象产品接口中声明的业务方法。

结构图

抽象工厂模式结构图.png

案例

以课程为例,假设一个课程需要提供录播视频、笔记、源码等资源才构成完整的课程。

创建 IVideo 和 INote 接口:

public interface IVideo{
    void record();
}
public interface INote{
    void edit();
}

创建抽象工厂类 CourseFactory :

public abstract class CourseFactory{
    public void init(){
        System.out.println("初始化数据");
    }
    
    protected abstract IVideo createNote();
    
    protected abstract INote createNote();
}

创建 Java 产品族,Java 视频 JavaVideo 类:

public class JavaVideo implements IVideo{
    public void record(){
        System.out.println("录制 Java 视频");
    }
}

扩展产品等级 Java 课堂笔记 JavaNote 类:

public class JavaNote implements INote{
    public void edit(){
        System.out.println("编写 Java 笔记");
    }
}

创建 Java 产品族的具体工厂:

public class JavaCourseFactory extends CourseFactory{
    public INote createNote(){
        super.init();
        return new JavaNote();
    }
    
    public IVideo createVideo(){
        super.init();
        return new JavaVideo();
    }
}

Python 产品同理:

public class PythonVideo implements IVideo{
    public void record(){
        System.out.println("录制 Python 视频");
    }
}

public class PythonNote implements INote{
    public void edit(){
        System.out.println("编写 Python 笔记");
    }
}

Python 产品族具体工厂:

public class PythonCourseFactory implements CourseFactory{
    public IVideo createVideo(){
        return new PythonVideo();
    }
    
    public INote createNote(){
        return new PythonNote();
    }
}

客户端调用代码:

public static void main(String[] args){
    JavaCourseFactory factory = new JavaCourseFactory();
    factory.createNote.edit();
    factory.createVideo.record();
}

开闭原则的倾斜性

在抽象工厂模式中,增加新的产品族很方便,但是增加新的产品等级结构很麻烦,抽象工厂模式的这种性质称为“开闭原则”的倾斜性。“开闭原则”要求系统对扩展开放,对修改关闭,通过扩展达到增强其功能的目的,对于涉及到多个产品族与多个产品等级结构的系统,其功能增强包括两方面:

  • 增加产品族:对于增加新的产品族,抽象工厂模式很好地支持了“开闭原则”,只需要增加具体产品并对应增加一个新的具体工厂,对已有代码无须做任何修改。
  • 增加新的产品等级结构:对于增加新的产品等级结构,需要修改所有的工厂角色,包括抽象工厂类,在所有的工厂类中都需要增加生成新产品的方法,违背了“开闭原则”。

总结

优点
  • 抽象工厂模式隔离了具体类的生成,使得客户并不需要知道什么被创建。由于这种隔离,更换一个具体工厂就变得相对容易,所有的具体工厂都实现了抽象工厂中定义的那些公共接口,因此只需改变具体工厂的实例,就可以在某种程度上改变整个软件系统的行为
  • 当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象
  • 增加新的产品族很方便,无须修改已有系统,符合开闭原则
缺点
  • 增加新的产品等级结构麻烦,需要对原有系统进行较大的修改,甚至需要修改抽象层代码,违背了开闭原则
适用场景
  • 一个系统不应当依赖于产品类实例如何被创建、组合和表达的细节,这对于所有类型的工厂模式都是很重要的,用户无须关心对象的创建过程,将对象的创建和使用解耦
  • 系统中有多于一个的产品族,而每次只使用其中某一产品族。可以通过配置文件等方式来使得用户可以动态改变产品族,也可以很方便地增加新的产品族
  • 属于同一个产品族的产品将在一起使用
  • 产品等级结构稳定,设计完成之后,不会向系统中增加新的产品等级结构或者删除已有的产品等级结构

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