• PHP设计模式——工厂模式


    原文: http://coderschool.cn/1521.html

    这一篇也讲得不错!!

    http://www.cnblogs.com/wangtao_20/p/3594192.html

    http://www.cnblogs.com/hongfei/archive/2012/07/07/2580776.html

    ------------------------------------------------------------------------------------------------

    PHP工厂模式就是用一个工厂方法来替换掉直接new对象的操作。

    在传统习惯中,如果要生成一个类的话,在代码中直接new一个对象,比如:

    1
    2
    3
    4
    5
    class Database{
        
    }
     
    $db = new Database();

    下面介绍工厂模式的操作方法:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    class Database{  
     
    }
     
    //创建一个工厂类
    class Factory
    {
       //创建一个静态方法
       static function createDatabase(){
           $db = new Database;
           return $db;
       }
    }

    那么,当我们想创建一个数据库类的话,就可以使用这样的方法:

    1
    $db = Factory::createDatabase();

    简单工厂模式比直接new一个对象的好处是,比如Database这个类在很多php文件中都有使用到,当Database这个类发生了某些变更,比如修改了类名、或者一些参数发生了变化,那这时候如果你使用的是$db = new Database这种传统方法生成对象,那么在所有包含这种生成对象的php文件代码中都要进行修改。而使用工厂模式,只要在工厂方法或类里面进行修改即可。而且工厂模式是其他设计模式的基础。

    对上面的简单工厂模式再进一步优化,比如:

    利用工厂类生产对象

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    <?php
    class Example
    {
        // The parameterized factory method
        public static function factory($type)
        {
            if (include_once 'Drivers/' . $type . '.php') {
                $classname = 'Driver_' . $type;
                return new $classname;
            } else {
                throw new Exception('Driver not found');
            }
        }
    }
     
    // Load a MySQL Driver
    $mysql = Example::factory('MySQL');
     
    // Load an SQLite Driver
    $sqlite = Example::factory('SQLite');
    ?>

    简单工厂模式又称静态工厂方法模式。从命名上就可以看出这个模式一定很简单。它存在的目的很简单:定义一个用于创建对象的接口。

    要理解工厂模式这个概念,让我们最好谈一下许多开发人员从事大型系统的艰苦历程。在更改一个代码片段时,就会发生问题,系统其他部分 —— 您曾认为完全不相关的部分中也有可能出现级联破坏。

    该问题在于紧密耦合 。系统某个部分中的函数和类严重依赖于系统的其他部分中函数和类的行为和结构。您需要一组模式,使这些类能够相互通信,但不希望将它们紧密绑定在一起,以避免出现联锁。

    在大型系统中,许多代码依赖于少数几个关键类。需要更改这些类时,可能会出现困难。例如,假设您有一个从文件读取的 User 类。您希望将其更改为从数据库读取的其他类,但是,所有的代码都引用从文件读取的原始类。这时候,使用工厂模式会很方便。

    看下实例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
        <?php
     
        interface IUser
        {
          function getName();
        }
     
        class User implements IUser
        {       
          public $id;
          public function __construct( $id ) { }
     
          public function getName()
          {
            return "Jack";
          }
        }

    传统方法使用 User 类,一般都是这样:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    //在页面1
    $obj = new User(1);
     
    //在页面2
    $obj2 = new User(2);
     
    //在页面3
    $obj3 = new User(3);
    ....

    这时候,由于新的需求,使得User类要新增个参数或者User类名称发生变化,User 类代码发生变动,即:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    class User implements IUser
    {
      public $id,$pre;
      public function __construct( $id , $pre = '') {...}
     
      public function getName()
      {
        return $this->pre."Jack";
      }
    }

    接着,恐怖的事情发生了,假设之前有 100 个页面引用了之前的 User 类,那么这 100 个页面都要发生相应的改动:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    //在页面1
    $obj = new User(1,'aaa');
     
    //在页面2
    $obj = new User(2,'aaa');
     
    //在页面3
    $obj = new User(3,'aaa');
    ...

    本来是一个小小的改动,但因紧密耦合的原因使得改动大吐血。而使用工厂模式则可以避免发生这种情况:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    //User类为变动前
    class UserFactory
    {
      public static function Create( $id )
      {
        return new User( $id );
      }
    }
     
    //页面1
    $uo1 = UserFactory::Create( 1 );
     
    //页面2
    $uo12 = UserFactory::Create( 2 );
    ....

    这时候需求变动,User 类也发生变动:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    class User implements IUser
    {
      public $id,$pre;
      public function __construct( $id , $pre = '') {...}
     
      public function getName()
      {
        return $this->pre."Jack";
      }
    }

    但是,我们不再需要去改动这 100 个页面,我们要改的仅仅是这个工厂类:

    1
    2
    3
    4
    5
    6
    7
    8
    //
    class UserFactory
    {
      public static function Create( $id,$pre = 'aaa' )
      {
        return new User( $id ,$pre);
      }
    }

    其他100个页面不用做任何改动,这就是工厂设计模式带来的好处。看下UML图:

    工厂模式uml图

  • 相关阅读:
    windows下phpunit installing[转]
    一个简单的文件后缀获取——不是通过文件名,而是文件内容
    二进制加法
    收藏一个韩国棒子的未知高度居中方法
    带超时+POST/GET方式的获取远程文件,利用file_get_contents
    较深度地递归转义过滤
    利用单元测试在每个层上对 PHP 代码进行检查[转IBM]
    提取TP的一个格式化为json的针对的原始类型函数
    分享一个正则方式的UTF8/GBK中文切割
    NewBaldwinFlash的登场(稍简单的DNN模块)
  • 原文地址:https://www.cnblogs.com/oxspirt/p/6816872.html
Copyright © 2020-2023  润新知