zoukankan      html  css  js  c++  java
  • 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更加灵活。

    相关文章:

    1. 星际争霸之php面向对象(一)

    2. 星际争霸之php面向对象(二)

    3. 星际争霸之php设计模式--简单工厂模式

    4. 星际争霸之php设计模式--工厂方法模式

    5. 星际争霸之php设计模式--抽象工厂模式

    6. 星际争霸之php设计模式--建造器模式

    7. 星际争霸之php设计模式--中介者模式

    8. 星际争霸之php设计模式--享元模式

    9. 星际争霸之php设计模式--代理模式

    10. 星际争霸之php设计模式--原型模式

    11. 星际争霸之php设计模式--备忘模式

    12. 星际争霸之php设计模式--模板模式

    13. 星际争霸之php设计模式--正面模式

    14. 星际争霸之php设计模式--状态模式

    15. 星际争霸之php设计模式--策略模式

    16. 星际争霸之php设计模式--组合模式

    17. 星际争霸之php设计模式--职责链模式

    18. 星际争霸之php设计模式--观察者模式

    19. 星际争霸之php设计模式--迭代器模式

    20. 星际争霸之php设计模式--适配器模式

  • 相关阅读:
    IDEA下同时使用Git和svn
    IDEA进行activiti-archetype-unittest脚手架的安装
    正则表达式
    关于JS堆栈与拷贝
    按值传递--
    JS---变量、作用域和内存问题
    laod
    待解决
    闭包2
    闭包1
  • 原文地址:https://www.cnblogs.com/davidhhuan/p/4248177.html
Copyright © 2011-2022 走看看