文档章节

抽象工厂模式(Abstract Factory Pattern)

自我修炼
 自我修炼
发布于 2017/02/09 20:56
字数 2617
阅读 1
收藏 0

抽象工厂模式

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. 简单工厂模式、工厂方法模式和抽象工厂模式的区别

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

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

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

© 著作权归作者所有

共有 人打赏支持
自我修炼
粉丝 0
博文 9
码字总数 11400
作品 0
昆明
项目经理
私信 提问
【设计模式之】 工厂模式

1、介绍 属于创建型设计模式,需要生成的对象叫做产品 ,生成对象的地方叫做工厂 。 使用场景:在任何需要生成复杂对象的地方,都可以使用工厂方法模式。 直接用new可以完成的不需要用工厂模...

卯金刀GG
02/27
0
0
php各种设计模式简单实践思考

前言 我一直觉得什么框架,版本,甚至语言对于一个coder来说真的不算什么,掌握一个特别高大上的一个框架或者是一个新的,少众的语言真的不算什么,因为你可以,我要花时间也可以,大家都是这...

michaelgbw
2016/06/13
0
0
代理模式(Proxy Pattern):动态代理 - 最易懂的设计模式解析

前言 今天我来全面总结开发中最常用的设计模式 - 代理模式中的动态代理模式 其他设计模式介绍 1分钟全面了解“设计模式” 单例模式(Singleton) - 最易懂的设计模式解析 简单工厂模式(Sim...

Carson_Ho
04/09
0
0
Java设计模式学习之工厂模式

在Java(或者叫做面向对象语言)的世界中,工厂模式被广泛应用于项目中,也许你并没有听说过,不过也许你已经在使用了。简单来说,工厂模式的出现源于增加程序序的可扩展性,降低耦合度。之所...

路小磊
07/21
0
10
设计模式: Java中的工厂设计模式

原文链接 https://github.com/shellhub/blog/issues/22 前言 工厂设计模式(Factory Design Pattern)属于创建模式之一,工厂设计模式在JDK,Spring,Stuts被广泛使用 当一个类或者接口有多个子类...

shellhub
08/22
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Mariadb二进制包安装,Apache安装

安装mariadb 下载二进制包并解压 [root@test-a src]# wget https://downloads.mariadb.com/MariaDB/mariadb-10.2.6/bintar-linux-glibc_214-x86_64/mariadb-10.2.6-linux-glibc_214-x86_64.t......

野雪球
今天
3
0
ConcurrentHashMap 高并发性的实现机制

ConcurrentHashMap 的结构分析 为了更好的理解 ConcurrentHashMap 高并发的具体实现,让我们先探索它的结构模型。 ConcurrentHashMap 类中包含两个静态内部类 HashEntry 和 Segment。HashEnt...

TonyStarkSir
今天
3
0
大数据教程(7.4)HDFS的java客户端API(流处理方式)

博主上一篇博客分享了namenode和datanode的工作原理,本章节将继前面的HDFS的java客户端简单API后深度讲述HDFS流处理API。 场景:博主前面的文章介绍过HDFS上存的大文件会成不同的块存储在不...

em_aaron
昨天
3
0
聊聊storm的window trigger

序 本文主要研究一下storm的window trigger WindowTridentProcessor.prepare storm-core-1.2.2-sources.jar!/org/apache/storm/trident/windowing/WindowTridentProcessor.java public v......

go4it
昨天
7
0
CentOS 生产环境配置

初始配置 对于一般配置来说,不需要安装 epel-release 仓库,本文主要在于希望跟随 RHEL 的配置流程,紧跟红帽公司对于服务器的配置说明。 # yum update 安装 centos-release-scl # yum ins...

clin003
昨天
11
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部