4. 星际争霸之php设计模式--工厂方法模式
题记
==============================================================================
本php设计模式专辑来源于博客(jymoz.com),现在已经访问不了了,这一系列文章是我找了很久才找到完整的,感谢作者jymoz的辛苦付出哦!
本文地址:http://www.cnblogs.com/davidhhuan/p/4248177.html
==============================================================================
PHP手册上提到的工厂模式,其实是简单工厂模式。这里来讨论简单工厂模式的扩展:工厂方法模式。
待解决的问题:虽然简单工厂解决了动态返回不同类型对象的问题,但是实际情况当中,往往在新建一个对象的时候,需要做一些额外处理,比如制造机枪兵的时候需要判断水晶矿是否大于50,而制造火焰兵的时候需要同时判断水晶矿是否大于50和气矿大于25,还有是否建造了研究院。如果把这些代码全部放到工厂制造类里面,会使得制造类很臃肿,而且随着工厂生产的对象的种类越来越多,工厂制造类的代码会越来越难以维护。
思路:简单工厂模式中的工厂类(兵种制造器的类)保持不变,增加一个制造接口,定义一个实际制造对象的方法,然后定义各个具体制造不同对象的工厂,同时要求这些工厂执行这个制造接口,让这些工厂去实现实际制造对象的方法。
工厂方法模式示例:
我们把机枪兵类和制造机枪兵的类的代码放入一个文件,Marine.php,它的代码如下:
<?php
//机枪兵类
class Marine
{
//机枪兵攻击的方法
public function attack()
{
echo 'Marine attack';
}
} //制造机枪兵的类,执行接口abstractCreator
class MarineCreator implements abstractCreator
{
//实际制造机枪兵的方法
public function realCreate()
{
//如果水晶矿大于50,这里只是作为说明,因为并不存在ore这个变量,也不考虑水晶少于50的处理
if($ore>50)
{
return new Marine();
}
}
}
?>
我们把火焰兵类和制造火焰兵的类的代码放入一个文件,Firebat.php,它的代码如下:
<?php
//火焰兵类
class Firebat
{
//火焰兵攻击的方法
public function attack()
{
echo 'Firebat attack';
}
} //制造火焰兵的类,执行接口abstractCreator
class FirebatCreator implements abstractCreator
{
//实际制造火焰兵的方法
public function realCreate()
{
//如果水晶矿大于50同时气矿大于25,并且研究院已经存在。这里只是作为说明,因为并不存在ore和gas和Academy变量,也不考虑资源不够时的处理
if($ore>50 && $gas>25 && Academy>1)
{
return new Firebat();
}
}
}
?>
主文件中的内容如下:
<?php //各个具体工厂必须执行的接口 interface abstractCreator
{
//规定各个具体工厂要实现的方法
public function realCreate();
} //兵种制造器的类,也就是主工厂
class BarracksCreator
{
//制造兵种的方法
public create($createWhat)
{
//根据输入的参数,动态的把需要的类的定义文件载入
require_once($createWhat.'.php'); //根据输入的参数,动态的获取相应的具体工厂的类的名字
$creatorClassName = $createWhat.'Creator'; //新建具体工厂对象
$creator = new $creatorClassName; //用具体工厂来实际生产,然后返回需要的类的对象。因为它们都执行了接口abstractCreator,所以肯定实现了方法realCreate()
return $creator->realCreate();
}
} //新建一个兵种制造器对象
$creator = new BarracksCreator(); //靠接收参数制造一个火焰兵对象
$troop1 = $creator->create('Marine');
$troop1->attack(); //靠接收参数制造一个机枪兵对象
$troop2 = $creator->create('Firebat');
$troop2->attack(); ?>
用途总结:工厂方法模式将新建对象的任务将给对应的具体工厂类,不必因为某些生产的对象需要进行额外处理而修改对外的主工厂。
实现总结:需要接收参数的主工厂类,比如上面兵种制造器BarracksCreator,还需要声明具体制造方法的一个接口,比如上面abstractCreator,然后定义具体生产各个产品的具体工厂类,每个具体工厂类必须执行接口abstractCreator,这样他们就必须实现制造对象的方法,比如上面的realCreate()。使用的时候只需要将参数传递给主工厂类工厂的生产方法create(),然后由create()根据参数生成具体工厂类的对象,并调用具体工厂类realCreate()获取制造的产品对象并返回,对外界使用来说,只需调用主工厂类工厂进行生产。
说明:其实这篇文章内的工厂方法模式和有些文章写的不同,标准的工厂模式往往是用一个抽象类来代替上面的接口abstractCreator,然后让所有的具体工厂类来继承它,但使用的时候,由于抽象类不能实例化(新建它的对象),所以经常是代码中直接new FirebatCreator(),但是简单工厂模式可以解决直接new的问题,所以我这里将简单工厂模式和工厂方法模式一起使用,使这里的示例更加实用。同时由于PHP是单继承,而执行接口的数量是没有限制的,所以使用接口abstractCreator更加灵活。
相关文章:
4. 星际争霸之php设计模式--工厂方法模式的更多相关文章
- 17. 星际争霸之php设计模式--职责链模式
题记==============================================================================本php设计模式专辑来源于博客(jymo ...
- 11. 星际争霸之php设计模式--备忘模式
题记==============================================================================本php设计模式专辑来源于博客(jymo ...
- 8. 星际争霸之php设计模式--享元模式
题记==============================================================================本php设计模式专辑来源于博客(jymo ...
- 7. 星际争霸之php设计模式--中介者模式
题记==============================================================================本php设计模式专辑来源于博客(jymo ...
- 6. 星际争霸之php设计模式--建造器模式
题记==============================================================================本php设计模式专辑来源于博客(jymo ...
- C++设计模式——工厂方法模式
本文版权归果冻说所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利.» 本文链接:http://www.jellythink.com/arch ...
- JAVA设计模式--工厂方法模式
工厂方法设计模式 抽象工厂角色: 这是工厂方法模式的核心,它与应用程序无关.是具体工厂角色必须实现的接口或者必须继承的父类.在java中它由抽象类或者接口来实现.具体工厂角色:它含有和具体业务逻辑有关 ...
- 深入浅出设计模式——工厂方法模式(Factory Method)
介绍在简单工厂模式中,我们提到,工厂方法模式是简单工厂模式的一个延伸,它属于Gof23中设计模式的创建型设计模式.它解决的仍然是软件设计中与创建对象有关的问题.它可以更好的处理客户的需求变化. 引入我 ...
- 设计模式--工厂方法模式(Factory method pattern)及应用
面向对象的好处: 通过封装,继承,多态把程序的耦合度降低. 用设计模式可以使程序更加灵活,容易修改,且易于复用. 1. 工厂方法模式 Define an interface for creating ...
随机推荐
- LightOj1388 - Trapezium Drawing(求梯形点的坐标)
题目链接:http://lightoj.com/volume_showproblem.php?problem=1388 题意:已知梯形的点A B的坐标,以及b c d的长度,求C D两点的坐标:默认A ...
- Arbitrage---poj2240(floyd)
题目链接:http://poj.org/problem?id=2240 题意:有n个国家的,有m个关系,每个关系的格式是:A B C表示1单位的A国货币可以换B单位C国货币:求是否存在一种方法使得货币 ...
- windows 访问 ubuntu虚拟机 django服务器 失败
配置ubuntu配置成桥接,在ubuntu虚拟机中运行django.py开发服务器.windows访问django失败. 虚拟机运行: python manage.py runserver 0.0.0 ...
- [代码片段]读取BMP文件
文件名mybmp.c //实现了读取24位BMP文件,还有一些测试信息 //定义mybmp.c里面用到的函数和相关头文件.常量 //参考了网友sailinghz在CSDN论坛的帖子:http://bb ...
- C# base和this
• 是否可以在静态方法中使用base和this,为什么? • base常用于哪些方面?this常用于哪些方面? • 可以base访问基类的一切成员吗? • 如果有三层或者更多继承,那么最下级派生类的b ...
- LeetCode Longest Palindrome
原题链接在这里:https://leetcode.com/problems/longest-palindrome/ 题目: Given a string which consists of lower ...
- Java Final, Finally, Finalize
Final is a Keyword, final can be used in three different ways: final variable final method final cla ...
- 学习WEb前端开发的需要哪些条件
第一阶段--HTML的学习. 超文本标记语言(HyperText Mark-up Language 简称HTML)是一个网页的骨架,无论是静态网页还是动态网页,最终返回到浏览器端的都是HTML代码,浏 ...
- 30天,O2O速成攻略【8.15济南站】
活动概况 时间:2015年08月15日13:30-16:30 地点:山东大学凤岐茶社(山东大学中心校区北门18号楼东连廊一层) 主办:APICloud.蚁巡 网址:www.apicloud.com 费 ...
- python or not python
python or not python 我挺喜欢 python 这种编程语言,它本身的丰富的动态特性让这种语言的表达能力很强,基本上 python 上写的一行代码,可实现 java 上 1.5 到 ...