抽象工厂模式(Abstract Factory Pattern)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/dgh_84/article/details/54782962

抽象工厂模式

1. 回顾
简单工厂模式:把所有的产品集中到一个工厂类中完成创建,而使用者只需提供工厂类的产品标识,即可创建不同的产品。

简单工厂中有三个角色:抽象产品角色(abstract class或interface)是所有具体产品角色的基类,具体产品角色是创建目标,工厂角色是根据传入的产品标识创建所需要的产品对象实例。

工厂方法模式:核心工厂类不再负责产品的创建,这样的核心类成为了一个抽象工厂角色,仅负责具体工厂子类必须实现的接口,将实际创建工作推迟到子类中。每个工厂负责创建一种产品,但所有负责创建的工厂必须有一个提供公共接口的基类(抽象工厂)

工厂方法模式中有四个角色:抽象工厂角色是所有具体工厂类的基类,只负责提供公共接口,具体工厂角色负责创建某一个具体产品,抽象产品角色是所有具体产品角色的基类,具体产品角色是创建目标。

简单工厂模式的弊端是随着产品的增加,而工厂类的判断逻辑也相对越来越复杂,及其不利于扩展和维护,我们使用工厂方法模式解决这样问题。

工厂方法模式的弊端是只能创建单一产品,每增加一种产品也必然要增加一个对应的具体工厂角色,这样随着产品的增加,而系统中的类也是成倍增加,这样为系统增加了负担。如果我们要创建多中产品怎么办?

2. 啥时候使用抽象工程方法模式
工厂老板不再满足现状,他想再生产一部平板电脑,而一个工厂只生产一中产品成本太高,如何充分利用这些工厂,是目前工厂老板最烦恼的事情,于是他便给每个工厂都增加了一条生产线,而不是单一的生产线了。含有多条生产线的工厂即为抽象工厂

3. 抽象工厂定义

抽象工厂模式(Abstract Factory Pattern):为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类。

抽象工厂引入了两个概念:

产品等级结构:即产品的继承结构,也就是说同一类型的产品必须拥有相同的基类,同一产品类型同出一源。如:小米手机、苹果手机、华为手机,它们都是同出自于抽象手机基类,那么它们便构成了产品等级结构。

产品族:是指由同一个工厂生产的,位于不同产品等级结构中的一组产品,即同一个工厂生产,但由不同类型的生产线(同一条生产线生产一同一种产品)生产的一组产品;我们还可以认为是产品族就是一个品牌,如:小米品牌、苹果品牌和华为品牌,但是每个品牌生产多种产品,即由多个产品构成一个品牌。

分析:抽象工厂类提供了多个不同类型的公共接口,且每个公共接口创建同一类型的产品。

举个例子:工厂基类相当于一个集团,集团下辖很多的生产工厂,但每个生产工厂能生产多种类型的产品,如:小米工厂可以生产小米手机、小米平板和小米电视等。

4. 该模式中包含的角色及其职责

1)、Factory:抽象工厂角色
是抽象工厂模式的核心,与应用程序无关。任何在模式中创建的工厂必须实现它所提供的公共接口。
2)、ConcreteFacory:具体工厂角色
这是实现抽象工厂接口的具体工厂类,包含与应用程序密切相关的逻辑,并且受到应用程序调用以创建产品对象。
3)、Product:抽象产品角色
抽象工厂模式所创建对象的基类,也就是产品对象的共同父类或共同拥有的接口。
4)、ConcreteProduct:具体产品角色
这个角色实现了抽象产品角色所定义的接口。某具体产品有专门的具体工厂创建。

这里写图片描述

不废话了,看下面代码!

5. 撸代码
PHP代码哦


/**
 * 抽象产品角色:IPhoneProduct
 *
 */
interface IPhoneProduct
{
    /**
     * 抽象产品角色提供的 公共接口 创建手机
     */
    public function createMobilePhone();
}
/**
 * 具体产品角色:ConcreteIPhoneProduct 生产苹果手机
 *
 */
class ConcreteIPhoneProduct implements IPhoneProduct
{
    /**
     * 抽象产品角色提供的 公共接口 创建苹果手机
     */
    public function createMobilePhone(){
        //具体实现代码
    }
}

/**
 * 具体产品角色:ConcreteXiaomiProduct 生产小米手机
 *
 */
class ConcreteXiaomiProduct implements IPhoneProduct
{
    /**
     * 抽象产品角色提供的 公共接口 创建小米手机
     */
    public function createMobilePhone(){
        //具体实现代码
    }
}
/**
 * 抽象产品角色:ITabletPCProduct
 *
 */
interface ITabletPCProduct
{
    /**
     * 抽象产品角色提供的 公共接口 创建平板电脑
     */
    public function createTabletPC();
}
/**
 * 具体产品角色:ConcreteXiaomiTabletPC 生产小米平板电脑
 * @author admin
 *
 */
class ConcreteXiaomiTabletPC
{
    /**
     * 抽象产品角色提供的 公共接口 创建小米平板电脑
     */
    public function createTabletPC(){
        //具体实现代码
    }
}
/**
 * 具体产品角色:ConcreteIPhoneTabletPC 生产苹果平板电脑
 * @author admin
 *
 */
class ConcreteIPhoneTabletPC
{
    /**
     * 抽象产品角色提供的 公共接口 创建苹果平板电脑
     */
    public function createTabletPC(){
        //具体实现代码
    }
}
/**
 * 抽象工厂方法角色:ICreatorFactory
 *
 */
interface ICreatorFactory
{
    /**
     * 抽象工厂角色提供 公共接口方法   创建手机
     */
    public function createMobilePhone();
    /**
     * 抽象工厂角色提供 公共接口方法 创建平板电脑
     */
    public function createTabletPC();
}
/**
 * 具体工厂角色:ConcreteXiaomiFactory 生产小米手机
 *
 */
class ConcreteXiaomiFactory implements ICreatorFactory
{
    /**
     * 抽象工厂方法角色提供 公共接口方法   创建小米手机
     * @return IProduct
     */
    public function createMobilePhone(){
        return new ConcreteXiaomiProduct();
    }
    /**
     * 抽象工厂角色提供 公共接口方法 创建小米平板电脑
     */
    public function createTabletPC(){
        return new ConcreteXiaomiTabletPC();
    }

}
/**
 * 具体工厂角色:ConcreteIPhoneFactory 生产苹果手机
 *
 */
class ConcreteIPhoneFactory implements ICreatorFactory
{
    /**
     * 抽象工厂方法角色提供 公共接口方法   创建苹果手机
     * @return IProduct
     */
    public function createMobilePhone(){
        return new ConcreteIPhoneProduct();
    }
    /**
     * 抽象工厂角色提供 公共接口方法 创建苹果平板电脑
     */
    public function createTabletPC(){
        return new ConcreteIPhoneTabletPC();
    }
}

/**
 * 测试抽象工厂模式
 *
 */
class TestAbstractFactory
{
    //测试方法
    public function Test(){
        //创建苹果手机
        $iphone = (new ConcreteIPhoneFactory())->createMobilePhone();
        //创建苹果平板电脑
        $iphoneTabletPC= (new ConcreteIPhoneFactory())->createTabletPC();

        //创建小米手机
        $xiaomi = (new ConcreteXiaomiFactory())->createMobilePhone();
        //创建小米平板电脑
        $xiaomiTabletPC = (new ConcreteXiaomiFactory())->createTabletPC();
    }
}

6.抽象工厂模式的优点

它分离了具体的类
它使得易于交换产品系列
它有利于产品的一致性

7.抽象工厂模式的缺点

难以支持新种类的产品,由于在抽象工厂中规定了所有可能被创建的产品类型,要支持新种类的产品就必须对接口进行扩展,而这将涉及到对抽象工厂角色及其所有子类(具体工厂)的修改,显然会带来极其不便。

新增不同类型的产品时比较麻烦,要添加具体产品类,同时要修改抽象工厂接口,同时要修改抽象工厂的所有子类和并新增新的产品类的具体工厂。
8. 使用场景

一个系统不应当依赖于产品类实例如何被创建、组合和表达的细节,这对于所有形态的工厂模式都很重要。

这个系统有多于一个的产品族,而系统只消费其中某一个产品族。

同属于同一个产品族的产品是在一起使用的,这一约束必须在系统中的设计中体现出来。

系统提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于实现。

9. 简单工厂模式、工厂方法模式和抽象工厂模式的区别

简单工厂模式:所有产品由一个工厂集成创建,并提供一个带有产品标识的方法供外界调用,使用者只需关心与产品标识相对应的产品即可。简单工厂模式有三个要素组成,分别是工厂类集成所有产品的创建,只向外提供一个带有产品标识的方法,抽象产品类是所有具体产品的父类,只负责对具体产品提供公共接口,具体产品类是创建目标,负责实现抽象产品类中的公共接口。

工厂方法模式:所有产品的创建,被分离到子工厂中创建,并且每个工厂都必须有一个父类,同时每个工厂只负责创建一种类型的产品。工厂方法模式有四个要素组成,分别是抽象工厂类是所有具体工厂类的父类,并且只负责提供公共接口,具体工厂类是负责创建具体产品对象的实例类,但只能创建一种类型的产品,抽象产品类是所有具体产品类的父类,只负责对具体产品类提供公共接口,具体产品类是创建目标,负责实现抽象产品类中的公共接口。

抽象工厂模式:同样与工厂方法模式一样,将所有产品的创建分离到子工厂,并且每个工厂必须有一个父类,同时每个工厂至少要负责创建两种(及两种以上)类型的产品。抽象工厂模式有四个要素组成,分别是抽象工厂类是所有具体工程类的父类,并且只负责提供公共接口,而公共接口至少要提供两种(及两种以上)类型产品的创建,具体工厂类负责创建产品对象的实例类,抽象产品类是所有具体产品类的父类,只负责对具体参评类提供公共接口,具体产品类是创建目标,负责实现抽象产品类中的公共接口。

猜你喜欢

转载自blog.csdn.net/dgh_84/article/details/54782962
今日推荐