文档章节

抽象工厂模式(Abstract Factory Pattern)

自我修炼
 自我修炼
发布于 2017/02/09 20:56
字数 2617
阅读 1
收藏 0
点赞 0
评论 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
昆明
项目经理
代理模式(Proxy Pattern):动态代理 - 最易懂的设计模式解析

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

Carson_Ho ⋅ 04/09 ⋅ 0

【设计模式之】 工厂模式

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

卯金刀GG ⋅ 02/27 ⋅ 0

设计模式分类与原则

创建型模式 这些设计模式提供了一种在创建对象的同时隐藏创建逻辑的方式,而不是使用 new 运算符直接实例化对象。这使得程序在判断针对某个给定实例需要创建哪些对象时更加灵活。 工厂模式(...

晨猫 ⋅ 03/12 ⋅ 0

[设计模式]简单工厂模式

简介 简单工厂模式 (Simple Factory) 又叫静态工厂方法(Static Factory Method)模式。 简单工厂模式通常是定义一个工厂类,这个类可以根据不同变量返回不同类的产品实例。 简单工厂模式是一...

静默虚空 ⋅ 2015/06/03 ⋅ 0

设计模式梳理(一)

设计模式梳理(一) 总体来说设计模式分为三大类: @案例源码地址:https://gitlab.com/lxqxsyu/DisgnPattern 创建型模式 简单工厂模式 工厂类是整个模式的关键。它包含必要的判断逻辑,能够...

lxq_xsyu ⋅ 2017/11/02 ⋅ 0

设计模式学习(二):软件设计与模式

模式与设计的关系   每个模式都描述了某个特定场景中一个特定问题的约束因素/动机和关系,并为设计者提供一种解决这些问题的优雅方案。换句话说,模式仅仅是描述了特定场景下的关系和约束因...

技术小美 ⋅ 2017/11/12 ⋅ 0

设计模式C++实现--AbstractFactory模式

抽象工厂模式 抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳...

黑客画家 ⋅ 06/04 ⋅ 0

简单工厂、工厂方法、抽象工厂、策略模式、策略与工厂的区别

转载:原地址http://www.cnblogs.com/zhangchenliang/p/3700820.html 简单工厂、工厂方法、抽象工厂、策略模式、策略与工厂的区别 结合简单示例和UML图,讲解工厂模式简单原理。 一、引子 话说...

法斗斗 ⋅ 05/08 ⋅ 0

设计模式之简单工厂模式学习笔记

定义 简单工厂模式又称静态工厂模式。可以根据参数的不同返回不同类的实例。定义一个类来创建其它类的实例。 角色 简单工厂模式包含如下角色 Factory:工厂角色 Product:抽象产品角色 Conc...

Javahih ⋅ 04/24 ⋅ 0

Net设计模式实例之代理模式(Proxy Pattern)

一、代理模式简介(Brief Introduction) 代理模式(Proxy Pattern)对其他对象提供一种代理以控制对这个对象的访问。 二、解决的问题(What To Solve) 1、远程代理 远程代理,也就是为了一...

余二五 ⋅ 2017/11/23 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

JavaScript零基础入门——(八)JavaScript的数组

JavaScript零基础入门——(八)JavaScript的数组 欢迎大家回到我们的JavaScript零基础入门,上一节课我们讲了有关JavaScript正则表达式的相关知识点,便于大家更好的对字符串进行处理。这一...

JandenMa ⋅ 今天 ⋅ 0

sbt网络问题解决方案

转自:http://dblab.xmu.edu.cn/blog/maven-network-problem/ cd ~/.sbt/launchers/0.13.9unzip -q ./sbt-launch.jar 修改 vi sbt/sbt.boot.properties 增加一个oschina库地址: [reposit......

狐狸老侠 ⋅ 今天 ⋅ 0

大数据,必须掌握的10项顶级安全技术

我们看到越来越多的数据泄漏事故、勒索软件和其他类型的网络攻击,这使得安全成为一个热门话题。 去年,企业IT面临的威胁仍然处于非常高的水平,每天都会看到媒体报道大量数据泄漏事故和攻击...

p柯西 ⋅ 今天 ⋅ 0

Linux下安装配置Hadoop2.7.6

前提 安装jdk 下载 wget http://mirrors.hust.edu.cn/apache/hadoop/common/hadoop-2.7.6/hadoop-2.7.6.tar.gz 解压 配置 vim /etc/profile # 配置java环境变量 export JAVA_HOME=/opt/jdk1......

晨猫 ⋅ 今天 ⋅ 0

crontab工具介绍

crontab crontab 是一个用于设置周期性被执行的任务工具。 周期性执行的任务列表称为Cron Table crontab(选项)(参数) -e:编辑该用户的计时器设置; -l:列出该用户的计时器设置; -r:删除该...

Linux学习笔记 ⋅ 今天 ⋅ 0

深入Java多线程——Java内存模型深入(2)

5. final域的内存语义 5.1 final域的重排序规则 1.对于final域,编译器和处理器要遵守两个重排序规则: (1)在构造函数内对一个final域的写入,与随后把这个被构造对象的引用赋值给一个引用...

江左煤郎 ⋅ 今天 ⋅ 0

面试-正向代理和反向代理

面试-正向代理和反向代理 Nginx 是一个高性能的反向代理服务器,但同时也支持正向代理方式的配置。

秋日芒草 ⋅ 今天 ⋅ 0

Spring 依赖注入(DI)

1、Setter方法注入: 通过设置方法注入依赖。这种方法既简单又常用。 类中定义set()方法: public class HelloWorldOutput{ HelloWorld helloWorld; public void setHelloWorld...

霍淇滨 ⋅ 昨天 ⋅ 0

马氏距离与欧氏距离

马氏距离 马氏距离也可以定义为两个服从同一分布并且其协方差矩阵为Σ的随机变量之间的差异程度。 如果协方差矩阵为单位矩阵,那么马氏距离就简化为欧氏距离,如果协方差矩阵为对角阵,则其也...

漫步当下 ⋅ 昨天 ⋅ 0

聊聊spring cloud的RequestRateLimiterGatewayFilter

序 本文主要研究一下spring cloud的RequestRateLimiterGatewayFilter GatewayAutoConfiguration @Configuration@ConditionalOnProperty(name = "spring.cloud.gateway.enabled", matchIfMi......

go4it ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部