1. PHP设计模式之简单工厂和工厂模式实例分析

     更新时间:2019年03月25日 10:48:58   作者:12345987   我要评论

    这篇文章主要介绍了PHP设计模式之简单工厂和工厂模式,结合实例形式分析了php设计模式中工厂模式的实现方法及相关操作注意事项,需要的朋友可以参考下

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

    工厂模式是创建型模式的一种,分为简单工厂模式,工厂模式,抽象工厂模式,简单工厂可以称之为工厂模式的一个特例

    先用一段简单的代码说明一下,现在假设我们是顾客,需要苹果味饮料和香?#27573;?#39278;料

    <?php
    class AppleDrink{
      function getDrinkName()
      {
        echo '苹果饮料';
      }
    }
    class BananaDrink{
      function getDrinkName()
      {
        echo '香蕉饮料';
      }
    }
    //顾客1
    $apple = new AppleDrink();
    $apple->getDrinkName();
    echo "<br/>";
    $banana = new BananaDrink();
    $banana->getDrinkName();
    echo "<br/>";
    //顾客2
    $apple1 = new AppleDrink();
    $apple1->getDrinkName();
    echo "<br/>";
    $banana1 = new BananaDrink();
    $banana1->getDrinkName();
    
    

    运行结果:

    苹果饮料
    香蕉饮料
    苹果饮料
    香蕉饮料

    这是最基本的写法,顾客和饮料是强耦合关系,也就是咱们平常说的硬编码

    有一天,老板觉得AppleDrink这个名字在国内不好卖,想要改成Xingmu(醒目)这种接中国地气的名字(麦当劳改成金拱门)

    你会发现,需要去代码中找到每一处NEW的地方,全部改成new Xingmu()

    如果它还有其他的初始化步骤,就更是噩梦,很可能会引起一些不必要的麻烦

    下面咱们用简单工厂模式,更改一下这个文件

    <?php
    class AppleDrink{
      function getDrinkName()
      {
        echo '苹果饮料';
      }
    }
    class BananaDrink{
      function getDrinkName()
      {
        echo '香蕉饮料';
      }
    }
    class FruitFactory{
      function makeDrink($fruit){
        if ($fruit == 'apple'){
          return new AppleDrink();
        }elseif ($fruit == 'banana'){
          return new BananaDrink();
        }
      }
    }
    $factory = new FruitFactory();
    $apple = $factory->makeDrink('apple');
    $apple->getDrinkName();
    echo "<br/>";
    $banana = $factory->makeDrink('banana');
    $banana->getDrinkName();
    echo "<br/>";
    $apple1 = $factory->makeDrink('apple');
    $apple1->getDrinkName();
    echo "<br/>";
    $banana1 = $factory->makeDrink('banana');
    $banana1->getDrinkName();
    
    

    运行结果:

    苹果饮料
    香蕉饮料
    苹果饮料
    香蕉饮料

    现在我们发现,假如说老板想改名字,我只需要把FruitFactory里的new AppleDrink改为new Xingmu()即可,其他地方都不需要改动,也不用翻代码找哪些地方用new了,实现了顾客和饮料之间的解耦,也符合面向对象的设计思想,我只是想要一瓶饮料,我并不需要了解这个饮料是怎么制造出来的

    这就是简单工厂模式,用户在使用时可以直接根据工厂类去创建所需的实例,而无需了解这些对象是如何创建以及如何组织?#27169;?#22806;界与具体类隔离开来,耦合性低,有利于整个软件体系结构的优化,适用于工厂类负责创建的对象比较少,客户只知?#26469;?#20837;了工厂类的参数,对于如何创建对象(逻辑)不关?#27169;?#31616;单工厂模式又叫静态工厂模式 可以把工厂类的方法写成静态方法 在不需要实例化工厂的前提下 直接调用静态方法 返回所需实例

    好?#27169;?#37027;么接下来,问题又来了,公司准备多元化产品,增加桔子味饮料,那么我们需要怎么做呢,首先要增加桔子味饮料类,然后需要在工厂里增?#20248;?#26029;,当水果标识是orange的时候,返回桔子味饮料

    class OrangeDrink{
      function getDrinkName()
      {
        echo '桔子味饮料';
      }
    }
    class FruitFactory{
      function makeDrink($fruit){
        if ($fruit == 'apple'){
          return new AppleDrink();
        }elseif ($fruit == 'banana'){
          return new BananaDrink();
        }elseif ($fruit == 'orange'){
          return new OrangeDrink();
        }
      }
    }
    
    

    然后当以后每次需要增加新的产品时,我们都需要更改工厂文件,当对象生成复杂的时候,这个工厂文件会越来越大,更改或许会引起一些意想不到的问题

    面向对象的设计原则,对扩展开放,对更改关闭,那么有没有办法,在不更?#33041;?#26377;代码的基础上,增?#30828;?#21697;呢

    答案是有?#27169;?#21681;们再改写一下这个方法

    <?php
    interface Drink{
      function getDrinkName();
    }
    class AppleDrink implements Drink{
      function getDrinkName()
      {
        echo '苹果味饮料';
      }
    }
    class BananaDrink implements Drink{
      function getDrinkName()
      {
        echo '香?#27573;?#39278;料';
      }
    }
    interface FruitFactory{
      function makeDrink();
    }
    class AppleFactory implements FruitFactory{
      function makeDrink()
      {
        return new AppleDrink();
      }
    }
    class BananaFactory implements FruitFactory{
      function makeDrink()
      {
        return new BananaDrink();
      }
    }
    $appleFactory = new AppleFactory();
    $apple = $appleFactory->makeDrink();
    $apple->getDrinkName();
    echo "<br/>";
    $bananaFactory = new BananaFactory();
    $banana = $bananaFactory->makeDrink();
    $banana->getDrinkName();
    
    

    运行结果:

    苹果味饮料
    香?#27573;?#39278;料

    现在当再次需要增加桔子味饮料时,只需要增加桔子味饮料产品和桔子味饮料工厂即可,不需要改动原来的代码

    class OrangeDrink implements Drink{
      function getDrinkName()
      {
        echo '桔子味饮料';
      }
    }
    class OrangeFactory implements FruitFactory{
      function makeDrink()
      {
        return new OrangeDrink();
      }
    }
    
    

    这就是工厂模式,它是简单工厂模式的衍生,解决了许多简单工厂模式的问题。首先完全实现开闭原则,实现了对扩展开放,对更改关闭。其次实现更复杂的层次结构,可以应用于产品结果复杂的场合。工厂方法模式是对简单工厂模式进行了抽象。有一个抽象的Factory类(可以是抽象类和接口),这个类将不在负责具体的产品生产,而是只制定一些规范,具体的生产工作由其子类去完成。在这个模式中,工厂类和产品类往往可以?#26469;味杂Α?#21363;一个抽象工厂对应一个抽象产品,一个具体工厂对应一个具体产品,这个具体的工厂就负责生产对应的产品。

    总结:

    无论是简单工厂模式,工厂方法模式,还是抽象工厂模式,他们都属于工厂模式,在形式和特点上也是极为相似?#27169;?#20182;们的最终目的都是为了解耦。在使用时,我们不必去在意这个模式到底工厂方法模式还是抽象工厂模式,因为他们之间的演变常常是令人琢磨不透的。经常你会发现,明明使用的工厂方法模式,当新需求来临,稍?#26377;薷模?#21152;入了一个新方法后,由于类中的产品构成了不同等级结构中的产品族,它就变成抽象工厂模式了;而对于抽象工厂模式,当减少一个方法使的提供的产品不再构成产品族之后,它就演变成了工厂方法模式。所以,在使用工厂模式时,只需要关心降低耦合度的目的是否达到了

    更多关于PHP相关内容?#34892;?#36259;的读者可查看本站专题:《php面向对象程序设计入门教程》、《PHP数组(Array)操作技巧大全》、《PHP基本语法入门教程》、《PHP运算与运算符用法总结》、《php字符串(string)用法总结》、《php+mysql数据库操作入门教程》及《php常见数据库操作技巧汇总

    希望本文所述?#28304;?#23478;PHP程序设计有所帮助。

    相关文章

    • 在PHP中养成7个面向对象的好习惯

      在PHP中养成7个面向对象的好习惯

      如果您?#24418;创?#31639;用 OO 原则创建应用程序,则使用 PHP 的面向对象(OO)的语言特性,这 7 个习惯将帮助您开始在过程编程与 OO 编程之间进行转换。
      2010-07-07
    • php批?#21487;境?#25968;据库下指定前缀的表以prefix_为例

      php批?#21487;境?#25968;据库下指定前缀的表以prefix_为例

      这篇文章主要介绍了如何用php批?#21487;境?#25968;据库下所有前缀为prefix_的表,这个功能比较实用,需要的朋友可以参考下
      2014-08-08
    • PDO版本问题 Invalid parameter number: no parameters were bound

      PDO版本问题 Invalid parameter number: no parameters were bou

      发现在客户的某个PHP版本下,执?#24515;?#31867;操作的时候,总是会报如下错误 Invalid parameter number: no parameters were bound,经google,发现是php版本过低导致
      2013-01-01
    • PHP session会话操作技巧小结

      PHP session会话操作技巧小结

      这篇文章主要介绍了PHP session会话操作技巧,结合实例形式详细总结分析了php中session会话操作的原理、配置方法、使用技巧与相关注意事项,需要的朋友可以参考下
      2016-09-09
    • 深入解析php中的foreach问题

      深入解析php中的foreach问题

      本篇文章是对php中的foreach问题进行了详细的分析介绍,需要的朋友参考下
      2013-06-06
    • php注册系统和使用Xajax?#35789;?#39564;证用户名是否被占用

      php注册系统和使用Xajax?#35789;?#39564;证用户名是否被占用

      这篇文章主要为大家详细介绍了php注册系统和使用Xajax?#35789;?#39564;证用户名是否被占用,具有一定的参?#25216;?#20540;,?#34892;?#36259;的小伙伴们可以参?#23478;?#19979;
      2017-08-08
    • php curl基本操作详解

      php curl基本操作详解

      怎?#35789;?#29992;cURL的基本方法?首先修改php.ini文件的设置,找到php_curl.dll,取消下在的注释extension=php_curl.dll,因为php默认是不开启cURL的
      2013-07-07
    • php打印输出棋盘的实现方法

      php打印输出棋盘的实现方法

      这篇文章主要介绍了php打印输出棋盘的实现方法,以实例形式分析了两种不同的实现方法,具有一定的参考借鉴价值,需要的朋友可以参考下
      2014-12-12
    • PHP和Java 集成开发详解分析 强强联合

      PHP和Java 集成开发详解分析 强强联合

      很久以前,有人从www上看到看?#25945;?#31354;上一个很亮的亮点,它就是Java语言,与此同时,在另一个地方一位梦想家也看到了一个亮点,它就是PHP.
      2008-11-11
    • php返回json数据函数实例

      php返回json数据函数实例

      这篇文章主要介绍了php返回json数据函数实例,详细讲述了json_encode()函数用法,在进行PHP数据库程序设计中非常具有实用价值,需要的朋友可以参考下
      2014-10-10

    最新评论

    山东群英会开奖查询