文档章节

抽象工厂模式(Abstract Factory Pattern)

自我修炼
 自我修炼
发布于 2017/02/09 20:56
字数 2617
阅读 27
收藏 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
昆明
项目经理
私信 提问
加载中
请先登录后再评论。
工作流管理系统--Pegasus WMS

Pegasus (飞马座)工作流管理系统包括一套技术标准工作流程应用程序中执行帮助许多不同的环境中,包括桌面、校园集群、网格、云。它弥补了科学领域和执行环境通过自 动映射到分布式资源的高层工...

匿名
2013/02/24
5.4K
0
全新Web编程的js框架--Flapjax

Flapjax是一种全新的、为满足基于客户端的Web应用的需求而设计的一种js框架。其主要特点包括: 事件驱动, 反应评价 基于web service的事件流抽象 提供web service扩展接口 Flapjax简单易学:...

匿名
2013/04/05
784
0
PHP OAuth API

PHP OAuth API可以授权访问的用户一个API使用OAuth协议。它抽象OAuth 1.0,1.0和2.0在同一个类,因此您可以使用相同的“获得一个令牌”授权访问代表当前用户的任何API支持任何版本的OAuth协议。...

匿名
2012/11/01
4K
0
异步Tor控制协议的实现--txtorcon

txtorcon是一个基于Twisted的异步Tor控制协议的实现。Twisted 是一个用Python写的事件驱动的网络引擎,和洋葱路由网络Tor是一个旨在促进人们的隐私和安全的互联网。它包括单元测试有96% +覆盖...

匿名
2012/11/23
619
0
ZBUS高可用HA介绍

请参考最新文档 http://zbus.io/guide/ha?menu=ha http://git.oschina.net/rushmore/zbus 1. ZBUS 高可用设计 Zbus高可用采用ZbusServer + TrackServer结合完成,相对于单机版本的zbus,客户...

少帮主
2015/12/21
5.9K
6

没有更多内容

加载失败,请刷新页面

加载更多

教师必备的7个免费下载教学课件网站

教学课件是教师教学的必备工具,好的课件可以帮助学生更好的融入课堂氛围,吸引学生关注课堂教学知识,帮助增进学生对教学知识的理解,从而更好的实现学习目的。本期,小编收集了比较好的7个...

V5codings
03/01
21
0
ubuntu 安装 oh my zsh

https://github.com/ohmyzsh/ohmyzsh https://ohmyz.sh/#install 安装 sudo apt-get install zsh -ysh -c "$(wget https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh ......

阿豪boy
32分钟前
7
0
自然语言处理中的语言模型简介

作者|Devyanshu Shukla 编译|Flin 来源|medium 在这篇文章中,我们将讨论关于语言模型(LM)的所有内容 什么是LM LM的应用 如何生成LM LM的评估 介绍 NLP中的语言模型是计算句子(单词序列)...

人工智能遇见磐创
今天
9
0
electron-vue跨平台桌面应用开发实战教程(十二)——集成加密版的sqlite3:sqlcipher

本文主要讲解集成及使用sqlcipher,一个可以加密的sqlite。sqlcipher官方npm地址:https://www.npmjs.com/package/@journeyapps/sqlcipher 由于和sqlite的功能一样,只是增加了加密的功能,所...

david_zh
今天
23
0
传统数据仓库搭建思路

该图为阿里云大学课程学习整理所得,在语雀平台制作。

wffger
今天
17
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部