定义

​ 定义一个用于创建对象的接口(抽象工厂类),让子类决定实例化哪一个类,工厂方法使得一个类的实例化延迟到其子类(抽象工厂类的子类)。

​ 工厂方法模式是简单工厂模式的进一步抽象和推广。在简单工厂模式中,当新增一个类时都需要改动一次工厂类方法。而工厂方法模式中将一个类的实例化延续到抽象工厂的子类,使得新增一个类时只需创建一个对应的工厂类即可。因此工厂方法模式符合开闭原则。

使用场景

工厂方法模式更适合需要创建一系列实例的场景。工厂方法模式的特点是将简单工厂模式的内部逻辑判断移到了客户端代码中进行,也就是工厂方法模式是通过在客户端决定实例化哪一个具体工厂来创建相应的实例。

如这样一个场景:几个大学生学雷锋做好事,帮一个老人家做家务活。分别用简单工厂模式和工厂方法模式实现如下:

//简单工厂模式
$leiFengA = SimpleFactory->CreateLeiFeng('学雷锋的大学生');
$leiFengA->BuyRice();
$leiFengB = SimpleFactory->CreateLeiFeng('学雷锋的大学生');
$leiFengB->Sweep();
$leiFengC = SimpleFactory->CreateLeiFeng('学雷锋的大学生');
$leiFengC->Wash();
//工厂方法模式
$factory = new UndergraduateFactory();
$leiFengA = factory->CreateLeiFeng();
$leiFengA->BuyRice();
$leiFengB = factory->CreateLeiFeng();
$leiFengB->Sweep();
$leiFengC = factory->CreateLeiFeng();
$leiFengC->Wash();

如果这时有个需求,由于大学生们毕业了各奔东西,没法再帮老人家做家务活了,需要由社区志愿者来代替他们做好事。那么修改上面客户端代码时,简单工厂模式需要将所有的“学雷锋的大学生”替换成社区志愿者。而工厂方法模式中,只需要将UndergraduateFactory()(学雷锋的大学生工厂)换成VolunteerFactory()(社区志愿者工厂)。

类图

PHP代码示例

//雷锋类
class LeiFeng
{
public function sweep()
{
echo '扫地';
} public function wash()
{
echo '洗衣';
} public function buyRice()
{
echo '买米';
}
}
//大学生
class Undergraduate extends LeiFeng
{ }
//社区志愿者
class Volunteer extends LeiFeng
{ }
//雷锋工厂类
abstract class LeiFengFactory
{
abstract public function createLeiFeng();
}
//学雷锋的大学生工厂类
class UndergraduateFactory extends LeiFengFactory
{
public function createLeiFeng()
{
return new Undergraduate();
}
}
//社区志愿者工厂类
class VolunteerFactory extends LeiFengFactory
{
public function createLeiFeng()
{
return new Volunteer();
}
}
//客户端
$factory = new UndergraduateFactory();
$leiFeng = $factory->createLeiFeng();
$leiFeng->sweep();

PHP之工厂方法模式(三)的更多相关文章

  1. 设计模式(三)工厂方法模式(Factory Pattern)

    一.引言 在简单工厂模式中讲到简单工厂模式的缺点,有一点是——简单工厂模式系统难以扩展,一旦添加新产品就不得不修改简单工厂方法,这样就会造成简单工厂的实现逻辑过于复杂,然而本专题介绍的工厂方法模式可以 ...

  2. 9、Cocos2dx 3.0游戏开发三查找值小工厂方法模式和对象

    重开发人员的劳动成果,转载的时候请务必注明出处:http://blog.csdn.net/haomengzhu/article/details/27704153 工厂方法模式 工厂方法是程序设计中一个 ...

  3. 9、Cocos2dx 3.0游戏开发找小三之工厂方法模式与对象传值

    重开发人员的劳动成果,转载的时候请务必注明出处:http://blog.csdn.net/haomengzhu/article/details/27704153 工厂方法模式 工厂方法是程序设计中一个 ...

  4. java之设计模式工厂三兄弟之工厂方法模式

    [学习难度:★★☆☆☆,使用频率:★★★★★] 简单工厂模式虽然简单,但存在一个很严重的问题.当系统中需要引入新产品时,由于静态工厂方法通过所传入参数的不同来创建不同的产品,这必定要修改工厂类的源代码 ...

  5. Unity C# 设计模式(三)工厂方法模式

    定义: 定义一个创建对象的接口(父类),由子类决定需要实例化哪一个类. 这样,核心工厂类成为了一个抽象角色,不再负责产品的创建,仅提供具体工厂类所必须实现的接口,这样进一步抽象化的好处是使得工厂方法模 ...

  6. Java设计模式学习笔记(三) 工厂方法模式

    前言 本篇是设计模式学习笔记的其中一篇文章,如对其他模式有兴趣,可从该地址查找设计模式学习笔记汇总地址 1. 简介 上一篇博客介绍了简单工厂模式,简单工厂模式存在一个很严重的问题: 就是当系统需要引入 ...

  7. 设计模式(三)——Java工厂方法模式

    工厂方法模式 1 看一个新的需求 披萨项目新的需求:客户在点披萨时,可以点不同口味的披萨,比如 北京的奶酪 pizza.北京的胡椒 pizza 或者是伦敦的奶酪 pizza.伦敦的胡椒 pizza. ...

  8. PHP设计模式(二)工厂方法模式(Factory Method For PHP)

    简单工厂简述: 简单工厂模式实现了生产产品类的代码跟客户端代码分离,在工厂类中你可以添加需要生成长跑的逻辑代码(new 产品类),但是问题来了,优秀的代码是符合"开闭原则"如果你要 ...

  9. C#设计模式(3)——工厂方法模式

    一.概念:定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂方法使一个类的实例化延迟到其子类. 二.代码实现 namespace 设计模式之工厂方法模式 { /// <summary&g ...

随机推荐

  1. devexpress entity framework 与 asp.net mvc的坑

    最近在做一个使用ASP.NET MVC DEVEXPRESS和EF的OA模块 遇到不少问题这里记录一下: 1 如果项目中存在多个上下文类(DBContext的派生类),在做数据迁移的时候需要在不同目录 ...

  2. js中的typeof和instanceof和===

    typeof: 用于判断number/string/boolean/underfined类型/function 不能判断:null和object ,不能区分object和Array instanceo ...

  3. yii pageTitle与Yii::app()->name的区别

    我们会在main中修改:  'name'=>'傻逼管理系统', 在视图页中:Yii::app()->name时,会输出  傻逼管理系统:可是当我们用$this->pageTitle时 ...

  4. Docker安装weblogic

    Docker容器安装weblogic详细教程 前提:已经安装后Docker,并且能正常使用 (1)获取镜像:  docker pull ismaleiva90/weblogic12 docker pu ...

  5. 3.1 if 条件分支语句

    Python条件语句是通过一条或多条语句的执行结果(True或者False)来决定执行的代码块. 获取条件语句的执行结果的过程就是真假值判断 #首先需要说明在Python中 #假值(False):0. ...

  6. uva 1151最小生成树

    先求一次最小生成树,可以排除n*(n*1)/2-(n-1)条边,每次利用二进制法枚举套餐的选择,套餐中的点直接处理,如果两个套餐有公共点直接合并,他们一定连通,然后枚举第一步最小生成树得到的n-1条边 ...

  7. Java中子类能继承父类的私有属性吗?

    前段时间去听老师讲课的时候,老师告诉我子类是可以继承父类所有的属性和方法的.当时我是极其疑惑的,因为之前学校考试时这个考点我记得很清楚:子类只能继承父类的非私有属性和方法.老师给我的解释是这样的--先 ...

  8. 分享一个Appium/selenium测试报告模板

    介绍 这个模板改编自 这位外国老哥 效果图 错误截图 录像 失败的case可以点击"view"查看报错信息, 也可以点击screenshot查看截图信息,更可以点击replay查看 ...

  9. Ubuntu版本更替所引发的“血案”

    Ubuntu版本更替所引发的"血案"       今天,我兴致很高的装了双系统,并且配置了Linux的网络,接下来就是安装一些软件,来实现我想达到的功能了,结果被一个小小的命令卡的 ...

  10. linux 邮件服务器

    邮件通信系统协议及概念:软件角色:MUA:邮件客户端MTA:邮件服务端MDA:邮件服务端模块邮件客户端:Mail User Agent,邮件用户代理邮件服务端:Mail Transfer Agent, ...