设计模式详解:Abstract Factory(抽象工厂)

Abstract Factory 抽象工厂

设计模式学习:概述

除夕前一天还在写学习笔记,我都佩服我自己了O(∩_∩)O

意图

提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。

抽象工厂将具体的类分离,因为一个工厂封装了创建产品对象的责任和过程,它将客户和类的实现分离。

一个具体工厂类只在应用初始化时出现一次,这使得换用另一个风格的工厂更加容易。由于一个抽象工厂创建了一个对象系列,因此更换工厂之后,工厂产品会立即发生改变。

同时,抽象工厂也可以解决产品匹配的问题。因为使用同一个工厂制造出来的产品,其风格一定是相同的,也就一定是互相兼容的。

稳定-变化的角度来看,抽象工厂在产品种类稳定的情况下,支持不同风格同种产品间的方便替换。缺点是,抽象工厂并不支持简单的添加产品种类。

代码案例

现在有一个用户界面工具包,它支持多种视感,我们以Motif和Presentation Manager为例。在每种视感下,都有几种功能相同的控件,这里以窗口(Window)和菜单(Menu)为例。

下面是一种解决方案:

Window MotifWindow PMWindow Menu MotifMenu PMMenu

我们用如下方法去初始化:

class APP
{
    
    
    void intiWindow()
    {
    
    
        ...
        Window *w;
    	w = new MotifWindow();
    	...
	}
    void intiMenu()
    {
    
    
        ...
		Menu *m
        m = new MotifMenu();
        ...
    }
}

显然,看上去,这样编写也没有什么问题。但是,首先,这使得用户(class APP编写者)需要显式地调用子类的构造函数,这可能违背了接口隔离原则,增加了程序的耦合度。再者,一旦我们需要变更产品风格,比如现在将控件风格变为PM,那么可能有很多的函数会被更改。甚至,如果我们忘记更改某一处产品创建的风格,而两种风格又是不兼容的,还很有可能导致非常难以察觉的Bug。

现在,我们意识到,如果我们选择了Motif风格,那么不管是Window, Menu,还是可能存在的其他产品,都一定是Motif风格的。既然如此,何不将所有产品的创建封装到一个类中呢?

下面是抽象工厂模式给出的解决方案。

解决方案:

class AbstractFactory{
    
    
    virtual Window* createWindow() = 0;
    virtual Menu* createMenu() = 0;
}

class MotifFactory
{
    
    
    Window* createWindow(){
    
    
        return new MotifWindow();
    }
    Menu* createMenu(){
    
    
        return new MotifMenu;
    }
}

class PMFactory
{
    
    
    Window* createWindow(){
    
    
        return new PMWindow();
    }
    Menu* createMenu(){
    
    
        return new PMMenu;
    }
}

那么,APP类只需要这样编写:

class APP
{
    
    
    AbstractFactory* factory; 
    APP(AbstractFactoy af):factory(af){
    
    }
    void intiWindow()
    {
    
    
        ...
        Window *w;
    	w = factory->createWindow();
    	...
	}
    void intiMenu()
    {
    
    
        ...
		Menu *m
        m = factory->createMenu();
        ...
    }
}

只需要在初始化时传入一个工厂参数即可。

解释

你或许可以从下面的类图中更好地理解Abstract Factory。

抽象工厂模式和工厂方法模式异曲同工,它们的主要区别在于:工厂方法针对单一产品设计工厂,而抽象工厂模式则针对一种风格,也就是说,通常,工厂方法的类中只产出一种产品,而抽象工厂类产出同一风格的多种产品。抽象工厂的针对性更强。

本文中大量使用产品这个词,简单来讲,这个词指的就是对象。具有平行功能的对象,比如MotifWindow和PMWindow,就被分为不同的风格。

当然,也不得不提到这一模式的弊端:难以支持新种类的产品。比如,突然要给工具包中增加一个ScrollBar控件,那么AbstractFactory基类中就必须添加相应的函数,导致所有的子类一并需要更改。那么,当产品的变更经常发生时,Abstract Factory就不再适用了。

总结

设计模式 Abstract Factory(抽象工厂)
稳定点: 生产出的产品种类。
变化点: 产品的风格。
效果: 将同一风格的对象创建封装到一个类中。
特点: 给定一个工厂,就可以调用它的方法便捷地从生产出同一风格的各种产品。

类图:

AbstractFactory CreateProductA() CreateProductB() ConcreteFactory1 CreateProductA() CreateProductB() ConcreteFactory2 CreateProductA() CreateProductB() AbstractProduct1 ProductA1 ProductB1 AbstractProduct2 ProductA2 ProductB2 Client AbstractFactory* af

2021.2.10 转载请标明出处

猜你喜欢

转载自blog.csdn.net/natrick/article/details/113786039