php设计模式之工厂方法模式分析【星际争霸游戏案例】


Posted in PHP onJanuary 23, 2020

本文实例讲述了php设计模式之工厂方法模式。分享给大家供大家参考,具体如下:

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更加灵活。

希望本文所述对大家PHP程序设计有所帮助。

PHP 相关文章推荐
PHP的单引号和双引号 字符串效率
May 27 PHP
php smarty 二级分类代码和模版循环例子
Jun 16 PHP
php 文件缓存函数
Oct 08 PHP
php从右向左/从左向右截取字符串的实现方法
Nov 28 PHP
php curl的深入解析
Jun 02 PHP
php求正负数数组中连续元素最大值示例
Apr 11 PHP
php使用parse_url和parse_str解析URL
Feb 22 PHP
学习php设计模式 php实现单例模式(singleton)
Dec 07 PHP
PHP+MySql+jQuery实现的&quot;顶&quot;和&quot;踩&quot;投票功能
May 21 PHP
PHP绕过open_basedir限制操作文件的方法
Jun 10 PHP
PHP耦合设计模式实例分析
Aug 08 PHP
THINKPHP-Apache服务器中使用Alias虚拟目录URL重写 隐藏index.php
Mar 09 PHP
php面向对象基础详解【星际争霸游戏案例】
Jan 23 #PHP
PHP数据源架构模式之表入口模式实例分析
Jan 23 #PHP
TP3.2.3框架文件上传操作实例详解
Jan 23 #PHP
php的RSA加密解密算法原理与用法分析
Jan 23 #PHP
PHP检查文件是否存在,不存在自动创建及读取文件内容操作示例
Jan 23 #PHP
PHP实现一个按钮点击上传多个图片操作示例
Jan 23 #PHP
利用PHP内置SERVER开启web服务(本地开发使用)
Jan 22 #PHP
You might like
session 的生命周期是多长
2006/10/09 PHP
桌面中心(三)修改数据库
2006/10/09 PHP
深入了解php4(2)--重访过去
2006/10/09 PHP
php+mysql开源XNA 聚合程序发布 下载
2007/07/13 PHP
火车采集器 免费版使出收费版本功能实现原理
2009/09/17 PHP
php.ini 配置文件的深入解析
2013/06/17 PHP
使用php验证复选框有效性的示例
2013/11/13 PHP
php的webservice的wsdl的XML无法显示问题的解决方法
2014/03/11 PHP
ThinkPHP框架整合微信支付之Native 扫码支付模式一图文详解
2019/04/09 PHP
爱恋千雪-US-AscII加密解密工具(网页加密)下载
2007/06/06 Javascript
改写一个简单的菜单 弹性大小
2010/12/02 Javascript
JQuery分别取得每行最后一列和最后一行的示例代码
2013/08/18 Javascript
jquery上传插件fineuploader上传文件使用方法(jquery图片上传插件)
2013/12/05 Javascript
js几秒以后倒计时跳转示例
2013/12/26 Javascript
浅谈jQuery异步对象(XMLHttpRequest)
2014/11/17 Javascript
浅谈javascript 函数内部属性
2015/01/21 Javascript
解决bootstrap中modal遇到Esc键无法关闭页面
2015/03/09 Javascript
AngularJS 使用$sce控制代码安全检查
2016/01/05 Javascript
Bootstrap CSS使用方法
2016/12/23 Javascript
BootStrap 标题设置跨行无效的解决方法
2017/10/25 Javascript
angularjs使用gulp-uglify压缩后执行报错的解决方法
2018/03/07 Javascript
vue.js将时间戳转化为日期格式的实现代码
2018/06/05 Javascript
vue+elementUI 复杂表单的验证、数据提交方案问题
2019/06/24 Javascript
推荐几个不错的console调试技巧实现
2019/12/20 Javascript
[02:05]2014DOTA2西雅图国际邀请赛 BBC第二天小组赛总结
2014/07/11 DOTA
[03:33]TI9战队采访 - Infamous
2019/08/20 DOTA
python实现文件分组复制到不同目录的例子
2014/06/04 Python
Python with的用法
2014/08/22 Python
Python 打印自己设计的字体的实例讲解
2021/01/04 Python
Hawes & Curtis官网:英国经典品牌
2019/07/27 全球购物
接口的多继承会带来哪些问题
2015/08/17 面试题
小学六一儿童节活动方案
2014/08/27 职场文书
2015年感恩节演讲稿(优选篇)
2015/03/20 职场文书
世界上超棒的8种逻辑思维
2019/08/06 职场文书
安装Ruby和 Rails的详细步骤
2022/04/19 Ruby
python双向链表实例详解
2022/05/25 Python