当前位置:  编程技术>php

php精粹 php设计模式

    来源: 互联网  发布时间:2014-08-30

    本文导语:  1,选择一个最合适的设计模式 没有任何事物是完美的,也没有人说过设计模式一个严格的放之四海而皆准的解决方法。因此你可以改变这些模式,使它们更适合手头的工作。对于某些设计模式而言,他们就是所属程序固有的天...

1,选择一个最合适的设计模式

没有任何事物是完美的,也没有人说过设计模式一个严格的放之四海而皆准的解决方法。因此你可以改变这些模式,使它们更适合手头的工作。对于某些设计模式而言,他们就是所属程序固有的天性;而对于其他的一些设计模式,你可以改变其自身的模式。模式之间互相配合、协同工作已经很常见。它们构成了整个应用(至少一部分)的基础。

2.单例模式
 

代码示例:

// The Database class represents our global DB connection
class Database{
  // A static variable to hold our single instance
  private static $_instance = null;
 
  // Make the constructor private to ensure singleton
  private function __construct()
  {
    echo 'constructor';
  }

  // A method to get our singleton instance
  public static function getInstance()
  {
    if (!(self::$_instance instanceof Database)) {
      self::$_instance = new Database();
    }
   
    return self::$_instance;
  }
}

$database = Database::getInstance();
var_dump($database);

问题:使用单例模式不能创建两个实例,可用Traits解决创建两个不同类型的实例的问题,但仍然不能解决创建两个相同实例的问题(可用注册表模式解决)。

创建两个不同类的实例 代码:
 

代码示例:
trait Singleton {
        private static $_instance = null;
       
        public static function getInstance() {
            $class = __CLASS__;
           
            if(!(self::$_instance instanceof $class)) {
                self::$_instance = new $class;
            }
           
            return self::$_instance;
        }
       
    }
    class DB {
    }
   
    class DBWriteConnection extends DB {
        use Singleton;
       
        private function __construct() {
            echo 'DBWriteConnection
';
        }
    }
   
    class DBReadConnection extends DB {
        use Singleton;
       
        private function __construct() {
            echo 'DBReadConnection
';
        }
    }
   
    $dbWriteConnection = DBWriteConnection::getInstance();
    var_dump($dbWriteConnection);

3.注册表模式
注册表模式仅仅是一个单独的全局类,在你需要的时候允许代码检索一个对象的相同实例,也可以在你需要的时创建另一个实例(一经要求将再次访问那些全局实例)。

Registry类:
 

代码示例:

class Registry {
  /**
   * @var array The store for all of our objects
   */
  static private $_store = array();
 
  /**
   * Add an object to the registry
   *
   * If you do not specify a name the classname is used
   *
   * @param mixed $object The object to store
   * @param string $name Name used to retrieve the object
   * @return void
   * @throws Exception
   */
  static public function add($object, $name = null)
  {
    // Use the classname if no name given, simulates singleton
    $name = (!is_null($name)) ?$name:get_class($object);
    if (isset(self::$_store[$name])) {
      throw new Exception("Object already exists in registry");
    }
   
    self::$_store[$name]= $object;
  }
 
  /**
   * Get an object from the registry
   *
   * @param string $name Object name, {@see self::set()}
   * @return mixed
   * @throws Exception
   */
  static public function get($name)
  {
    if (!self::contains($name)) {
      throw new Exception("Object does not exist in registry");
    }

    return self::$_store[$name];
  }
 
  /**
   * Check if an object is in the registry
   *
   * @param string $name Object name, {@see self::set()}
   * @return bool
   */
  static public function contains($name)
  {
    if (!isset(self::$_store[$name])) {
      return false;
    }
   
    return true;
  }
 
  /**
   * Remove an object from the registry
   *
   * @param string $name Object name, {@see self::set()}
   * @returns void
   */
  static public function remove($name)
  {
    if (self::contains($name)) {
      unset(self::$_store[$name]);
    }
  }
}
 

在类外部,使用Registry类:
 

代码示例:

require 'Registry.php';

class DBReadConnection {}
class DBWriteConnection {}

$read = new DBReadConnection;
Registry::add($read);

$write = new DBWriteConnection;
Registry::add($write);

// To get the instances, anywhere in our code:
$read = Registry::get('DBReadConnection');
$write = Registry::get('DBWriteConnection');

var_dump($read);
var_dump($write);
 

在类内部使用Registry表类,使用者不与Registry交互。

示例代码:
 

代码示例:

require 'Registry.php';

abstract class DBConnection {
  static public function getInstance($name = null)
  {
    // Get the late-static-binding version of __CLASS__
    $class = get_called_class();
    // Allow passing in a name to get multiple instances
    // If you do not pass a name, it functions as a singleton
    $name = (!is_null($name)) ? $name:$class;
    if (!Registry::contains($name)) {
      $instance = new $class();
      Registry::add($instance, $name);
    }
    return Registry::get($name);
  }
}

class DBWriteConnection extends DBConnection {
  public function __construct()
  {
     echo 'DBWriteConnection
';
  }
}

class DBReadConnection extends DBConnection {
  public function __construct()
  {
     echo 'DBReadConnection
';
  }
}

$dbWriteConnection = DBWriteConnection::getInstance('abc');
var_dump($dbWriteConnection);
$dbReadConnection = DBReadConnection::getInstance();
var_dump($dbReadConnection);

4.工厂模式
工厂(factory)模式制造对象,就像工业界与它同名的钢筋混泥土行业一样。通常,我们将工厂模式用于初始化相同抽象类或者接口的具体实现。

在通常方式下,虽然人们极少采用工厂模式,但是它仍是最适合初始化基于驱动安装的许多变种的一种。例如不同的配置、会话或缓存存储引擎。工厂模式的最大价值在于它可以将多个对象设置封装成单一、简单的方法调用。
 

代码示例:
/**
 * Log Factory
 *
 * Setup and return a file, mysql, or sqlite logger
 */
class Log_Factory {
  /**
   * Get a log object
   *
   * @param string $type The type of logging backend, file, mysql or sqlite
   * @param array $options Log class options
   */
  public function getLog($type = 'file', array $options)
  {
    // Normalize the type to lowercase
    $type = strtolower($type);
   
    // Figure out the class name and include it
    $class = "Log_" .ucfirst($type);
    require_once str_replace('_', DIRECTORY_SEPARATOR, $class) . '.php';
   
    // Instantiate the class and set the appropriate options
    $log = new $class($options);
    switch ($type) {
      case 'file':
        $log->setPath($options['location']);
        break;
      case 'mysql':
        $log->setUser($options['username']);
        $log->setPassword($options['password']);
        $log->setDBName($options['location']);
        break;
      case 'sqlite':
        $log->setDBPath($otions['location']);
        break;
    }
   
    return $log;
  }
}

5.迭代模式
迭代模式允许我们将foreach的性能添加到任何对象的内部存储数据,而不仅仅添加到公共属性。它覆盖了默认的foreach行为,并允许我们为循环注入业务逻辑。

(1)使用Iterator迭代器接口
 

代码示例:

class BasicIterator implements Iterator {
    private $key = 0;
    private $data = array(
        "hello",
        "world",
    ); 

    public function __construct() {
        $this->key = 0;
    }

    public function rewind() {
        $this->key = 0;
    }

    public function current() {
        return $this->data[$this->key];
    }

    public function key() {
        return $this->key;
    }

    public function next() {
        $this->key++;
        return true;
    }

    public function valid() {
        return isset($this->data[$this->key]);
    }
}

$iterator = new BasicIterator();
$iterator->rewind();

do {
  $key = $iterator->key();
  $value = $iterator->current();
  echo $key .': ' .$value . PHP_EOL;
} while ($iterator->next() && $iterator->valid());


$iterator = new BasicIterator();
foreach ($iterator as $key => $value) {
  echo $key .': ' .$value . PHP_EOL;
}

(2)使用RecursiveIteratorIterator迭代器遍历数组
 

代码示例:

$array = array(
  "Hello", // Level 1
  array(
    "World" // Level 2
  ),
  array(
    "How", // Level 2
    array(
      "are", // Level 3
      "you" // Level 3
    )
  ),
  "doing?" // Level 1
);

$recursiveIterator = new RecursiveArrayIterator($array);

$recursiveIteratorIterator = new RecursiveIteratorIterator($recursiveIterator);

foreach ($recursiveIteratorIterator as $key => $value) {
  echo "Depth: " . $recursiveIteratorIterator->getDepth() . PHP_EOL;
  echo "Key: " . $key . PHP_EOL;
  echo "Value: " .$value . PHP_EOL;
}

 (3)用FilterIterator迭代器实现过滤
 

代码示例:


    
 
 

您可能感兴趣的文章:

  • php设计模式之命令模式使用示例
  • php设计模式之单例模式使用示例
  • PHP 面向对象程序设计(oop)学习笔记(三) - 单例模式和工厂模式
  • PHP设计模式之观察者模式(Observer)详细介绍和代码实例
  • 编译php fast-cgi模式报错
  • php正则表达式中的非贪婪模式匹配
  • Nginx隐藏index.php和Pathinfo模式配置例子
  • php工厂模式实例代码
  • PHP中数据库单例模式的实现代码分享
  • PHP实现单例模式最安全的做法
  • php-fpm两种进程管理模式详解
  • php 正则表达式的子模式详解
  • php正则表达式的模式修正符和逆向引用使用介绍
  • php单例模式(Singleton Pattern)实例教程
  • php利用单例模式实现日志处理类库
  • PHP的MVC模式实现原理分析(一相简单的MVC框架范例)
  • PHP OPP机制和模式简介(抽象类、接口和契约式编程)
  • PHP正则表达式的逆向引用与子模式分析
  •  
    本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
    本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • 修改配置真正解决php文件上传大小限制问题(nginx+php)
  • IIS7配置PHP图解(IIS7+PHP_5.2.17/PHP_5.3.5)
  • PHP 5.4.19 和 PHP 5.5.3 发布及下载地址
  • php输入流php://input使用示例(php发送图片流到服务器)
  • 修改配置真正解决php文件上传大小限制问题(apache+php)
  • PHP转换器 HipHop for PHP
  • PHP去除html标签,php标记及css样式代码参考
  • PHP 框架 Pop php
  • PHP 'ext/soap/php_xml.c'不完整修复存在多个任意文件泄露漏洞
  • PHP的JavaScript框架 PHP.JS
  • php通过socket_bind()设置IP地址代码示例
  • php服务器探针显示php服务器信息
  • php安装完成后如何添加mysql扩展
  • PHP缓存加速器 Alternative PHP Cache (APC)
  • PHP的substr() 函数用法
  • PHP源文件加密工具 PHP Screw
  • PHP介绍及学习网站推荐
  • PHP自动化测试 PHP-QAT
  • php中操作memcache的类及成员列表及php下如何连接memched服务器
  • PHP 的 HTTP 客户端库 PHP Buzz
  • php中内置的mysql数据库连接驱动mysqlnd简介及mysqlnd的配置安装方式
  • PHP 调试工具 PHP_Dyn




  • 特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3