设计模式之抽象工厂

抽象工厂模式铜工厂方法模式同样,也是有抽象工厂、具体工厂、抽象产品、具体产品4个要素构成,可是抽象工厂中方法个数不一样,抽象产品的个数也不一样。那么这篇文章主要介绍一下抽象工厂。编程

说到抽象工厂不知道有没有些许的迷茫,笔者在刚刚接触的时候倒是很迷茫的,其中最难理解的可能就是抽象。什么是抽象?函数

抽象:抽象是从众多的事物中抽取出共同的、本质性的特征,而舍弃其非本质的特征的过程。具体地说,抽象就是人们在实践的基础上,对于丰富的感性材料经过去粗取精、去伪存真、由此及彼、由表及里的加工制做,造成概念、判断、推理等思惟形式,以反映事物的本质和规律的方法。 ——节选自百度百科spa

笔者的理解的抽象则是抽离实物的本质,去掉其中不中要的部分。但愿你们也能对抽象有一个简单的理解,既然理解了抽象,那么抽象工厂模式天然也是如此,文章中开头说到抽象工厂模式铜工厂方法模式同样,其实也不大相同,其实抽象工厂模式是工厂方法模式的升级版本,工厂方法模式只生产一个等级的产品,而抽象工厂模式可生产多个等级的产品。code

什么是抽象工厂模式

抽象工厂模式:是一种为访问类提供一个建立一组相关或相互依赖对象的接口,且访问类无须指定所要产品的具体类就能获得同族的不一样等级的产品的模式结构。然而笔者理解的抽象工厂是这样的,为建立一组相关或依赖的对象提供一个接口,并且无需指定他们的具体类。对象

使用抽象工厂模式通常要知足如下条件。blog

  1. 系统中有多个产品族,每一个具体工厂建立同一族但属于不一样等级结构的产品。
  2. 系统一次只可能消费其中某一族产品,即同族的产品一块儿使用。

抽象工厂定义了用于建立不一样产品的接口,但将实际的建立工做留给了具体工厂类。每一个工厂类型都对应一个特定的产品变体。在建立产品时,客户端代码调用的是工厂对象的构建方法,而不是直接调用构造函数(new操做符)。因为一个工厂对应一种产品变体,所以它建立的全部产品均可相互兼容。客户端代码仅经过其抽象接口与工厂和产品进行交互。该接口容许同一客户端代码与不一样产品进行交互。 你只需建立一个具体工厂类并将其传递给客户端代码便可。接口

抽象工厂模式优缺点

抽象工厂更像一个复杂版本的策略模式,策略模式经过更换策略来改变处理方式或者结果;而抽象工厂的客户端,经过更改工厂还改变结果。因此在使用的时候,就使用客户端和更换工厂,而看不到产品自己。产品

工厂方法目的是生产产品,因此能看到产品,并且还要使用产品。固然,若是产品在建立者内部使用,那么工厂方法就是为了完善建立者,从而可使用建立者。另外建立者自己是不能更换所生产产品的。it

优势
  1. 能够在类的内部对产品族中相关联的多等级产品共同管理,而没必要专门引入多个新的类来进行管理
  2. 当须要产品族时,抽象工厂能够保证客户端始终只使用同一个产品的产品组
  3. 增长新的产品更加容易,抽象工厂加强了程序的可扩展性,当增长一个新的产品族时,不须要修改原代码
缺点
  1. 当产品族中须要增长一个新的产品时,全部的工厂类都须要进行修改
  2. 增长了系统的抽象性和理解难度

示例

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

  1. 抽象工厂:提供了建立产品的接口,它包含多个建立产品的方法newProduct(),能够建立多个不一样等级的产品。
  2. 具体工厂:主要是实现抽象工厂中的多个抽象方法,完成具体产品的建立。
  3. 抽象产品:定义了产品的规范,描述了产品的主要特性和功能,抽象工厂模式有多个抽象产品。
  4. 具体产品:实现了抽象产品角色所定义的接口,由具体工厂来建立,它同具体工厂之间是多对一的关系。

类图以下所示:

image

代码示例:

// 抽象产品A接口
interface AbstractProductA {}
// 抽象产品B接口
interface AbstractProductB {}

// 抽象工厂接口
interface AbstractFactory {
    createProductA() : AbstractProductA;
    createProductB() : AbstractProductB;
}

// 具体工厂1
class ConcreteFactory1 implements AbstractFactory {
    constructor() {}
    public createProductA() : AbstractProductA {
        return new ConcreteProductA1();
    }
    public createProductB() : AbstractProductB {
        return new ConcreteProductB1();
    }
}

// 具体工厂2
class ConcreteFactory2 implements AbstractFactory {
    constructor() {}
    public createProductA() : AbstractProductA {
        return new ConcreteProductA2();
    }
    public createProductB() : AbstractProductB {
        return new ConcreteProductB2();
    }
}

// 具体产品A1
class ConcreteProductA1 implements AbstractProductA {}
// 具体产品A2
class ConcreteProductA2 implements AbstractProductA {}
// 具体产品B1
class ConcreteProductB1 implements AbstractProductB {}
// 具体产品B2
class ConcreteProductB2 implements AbstractProductA {}

// 使用
const factory1 : AbstractFactory = new ConcreteFactory1();
const factory2 : AbstractFactory = new ConcreteFactory2();
const productA1 : AbstractProductA = factory1.createProductA();
const productA2 : AbstractProductA = factory2.createProductA();
const productB1 : AbstractProductB = factory1.createProductB();
const productB2 : AbstractProductB = factory2.createProductB();

抽象工厂与工厂方法不一样

  1. 抽象工程关键在于产品之间的抽象关系,因此至少要两个产品;工厂方法在于生成产品,不关注产品间的关系,因此能够只生成一个产品。
  2. 抽象工厂中客户端把产品的抽象关系理清楚,在最终使用的时候,通常使用客户端,产品之间的关系是被封装固定的;而工厂方法是在最终使用的时候,使用产品自己。
  3. 抽象工厂的工厂是类;工厂方法的工厂是方法。

抽象工厂的工厂类就作一件事情生产产品。生产的产品给客户端使用,毫不给本身用。工厂方法生产产品,能够给系统用,能够给客户端用,也能够本身这个类使用。本身这个类除了这个工厂方法外,还能有其余功能性的方法。

给工厂方法模式加一个客户端,除了客户端都不用这个建立者。这个时候建立者就是工厂类了。然而抽象工厂模式中,在客户端内部编程时候,就能够把工厂类看成建立者。

总结

抽象工厂模式的扩展有必定的开闭原则倾斜性,当增长一个新的产品族时只需增长一个新的具体工厂,不须要修改原代码,知足开闭原则。当产品族中须要增长一个新种类的产品时,则全部的工厂类都须要进行修改,不知足开闭原则。另外一方面,当系统中只存在一个等级结构的产品时,抽象工厂模式将退化到工厂方法模式。

相关文章
相关标签/搜索