PHP常用的三种设计模式汇总

本篇文章是学习PHP中常用的三种设计模式的笔记及总结,不管采用哪一门语言开发什么,几乎都会使用到设计模式,我们为什么需要设计模式呢?它的诞生对于我们开发人员来说有什么样的作用与意义呢?

相信做iOS开发的人员对设计模式也会挺熟悉吧?比如单例设计模式、工厂设计模式、观察者模式、MVC框架结构设计模式等。

接下来我们一起来学习PHP中最常用的三种设计模式:单例设计模式、工厂设计模式和观察者设计模式。

单例设计模式

所谓单例模式,即在应用程序中最多只有该类的一个实例存在,一旦创建,就会一直存在于内存中!

单例设计模式常应用于数据库类设计,采用单例模式,只连接一次数据库,防止打开多个数据库连接。

一个单例类应具备以下特点:

单例类不能直接实例化创建,而是只能由类本身实例化。因此,要获得这样的限制效果,构造函数必须标记为private,从而防止类被实例化。

需要一个私有静态成员变量来保存类实例和公开一个能访问到实例的公开静态方法。

在PHP中,为了防止他人对单例类实例克隆,通常还为其提供一个空的私有__clone()方法。

单例模式的例子:


<?php

/**
* Singleton of Database
*/
class Database
{
  // We need a static private variable to store a Database instance.
  privatestatic $instance;

  // Mark as private to prevent it from being instanced.
  privatefunction__construct()
  {
    // Do nothing.
  }

  privatefunction__clone()
  {
    // Do nothing.
  }

  publicstatic functiongetInstance()
  {
    if (!(self::$instanceinstanceofself)) {
      self::$instance = newself();
    }

    returnself::$instance;
  }
}

$a =Database::getInstance();
$b =Database::getInstance();

// true
var_dump($a === $b);

工厂设计模式

工厂设计模式常用于根据输入参数的不同或者应用程序配置的不同来创建一种专门用来实例化并返回其对应的类的实例。

我们举例子,假设矩形、圆都有同样的一个方法,那么我们用基类提供的API来创建实例时,通过传参数来自动创建对应的类的实例,他们都有获取周长和面积的功能。


<?php

interfaceInterfaceShape
{
 functiongetArea();
 functiongetCircumference();
}

/**
* 矩形
*/
class Rectangle implementsInterfaceShape
{
  private $width;
  private $height;

  publicfunction__construct($width, $height)
  {
    $this->width = $width;
    $this->height = $height;
  }

  publicfunctiongetArea()
  {
    return $this->width* $this->height;
  }

  publicfunctiongetCircumference()
  {
    return 2 * $this->width + 2 * $this->height;
  }
}

/**
* 圆形
*/
class Circle implementsInterfaceShape
{
  private $radius;

  function__construct($radius)
  {
    $this->radius = $radius;
  }

  publicfunctiongetArea()
  {
    return M_PI * pow($this->radius, 2);
  }

  publicfunctiongetCircumference()
  {
    return 2 * M_PI * $this->radius;
  }
}

/**
* 形状工厂类
*/
class FactoryShape
{
  publicstatic functioncreate()
  {
    switch (func_num_args()) {
      case1:
      return newCircle(func_get_arg(0));
      case2:
      return newRectangle(func_get_arg(0), func_get_arg(1));
      default:
        # code...
        break;
    }
  }
}

$rect =FactoryShape::create(5, 5);
// object(Rectangle)#1 (2) { ["width":"Rectangle":private]=> int(5) ["height":"Rectangle":private]=> int(5) }
var_dump($rect);
echo "<br>";

// object(Circle)#2 (1) { ["radius":"Circle":private]=> int(4) }
$circle =FactoryShape::create(4);
var_dump($circle);

观察者设计模式

观察者模式是挺常见的一种设计模式,使用得当会给程序带来非常大的便利,使用得不当,会给后来人一种难以维护的想法。

什么是观察者模式?一个对象通过提供方法允许另一个对象即观察者 注册自己)使本身变得可观察。当可观察的对象更改时,它会将消息发送到已注册的观察者。这些观察者使用该信息执行的操作与可观察的对象无关。结果是对象可以相互对话,而不必了解原因。观察者模式是一种事件系统,意味着这一模式允许某个类观察另一个类的状态,当被观察的类状态发生改变的时候,观察类可以收到通知并且做出相应的动作;观察者模式为您提供了避免组件之间紧密耦。看下面例子你就明白了!


<?php

/*
观察者接口
*/
interfaceInterfaceObserver
{
  functiononListen($sender, $args);
  functiongetObserverName();
}

// 可被观察者接口
interfaceInterfaceObservable
{
  functionaddObserver($observer);
  functionremoveObserver($observer_name);
}

// 观察者抽象类
abstractclass Observer implementsInterfaceObserver
{
  protected $observer_name;

  functiongetObserverName()
  {
    return $this->observer_name;
  }

  functiononListen($sender, $args)
  {

  }
}

// 可被观察类
abstractclass Observable implementsInterfaceObservable
{
  protected $observers = array();

  publicfunctionaddObserver($observer)
  {
    if ($observerinstanceofInterfaceObserver)
    {
      $this->observers[] = $observer;
    }
  }

  publicfunctionremoveObserver($observer_name)
  {
    foreach ($this->observersas $index => $observer)
    {
      if ($observer->getObserverName() === $observer_name)
      {
        array_splice($this->observers, $index, 1);
        return;
      }
    }
  }
}

// 模拟一个可以被观察的类
class A extendsObservable
{
  publicfunctionaddListener($listener)
  {
    foreach ($this->observersas $observer)
    {
      $observer->onListen($this, $listener);
    }
  }
}

// 模拟一个观察者类
class B extendsObserver
{
  protected $observer_name = 'B';

  publicfunctiononListen($sender, $args)
  {
    var_dump($sender);
    echo "<br>";
    var_dump($args);
    echo "<br>";
  }
}

// 模拟另外一个观察者类
class C extendsObserver
{
  protected $observer_name = 'C';

  publicfunctiononListen($sender, $args)
  {
    var_dump($sender);
    echo "<br>";
    var_dump($args);
    echo "<br>";
  }
}

$a = new A();
// 注入观察者
$a->addObserver(new B());
$a->addObserver(new C());

// 可以看到观察到的信息
$a->addListener('D');

// 移除观察者
$a->removeObserver('B');

// 打印的信息:
// object(A)#1 (1) { ["observers":protected]=> array(2) { [0]=> object(B)#2 (1) { ["observer_name":protected]=> string(1) "B" } [1]=> object(C)#3 (1) { ["observer_name":protected]=> string(1) "C" } } }
// string(1) "D"
// object(A)#1 (1) { ["observers":protected]=> array(2) { [0]=> object(B)#2 (1) { ["observer_name":protected]=> string(1) "B" } [1]=> object(C)#3 (1) { ["observer_name":protected]=> string(1) "C" } } }
// string(1) "D"

小结

初入PHP的世界,目前只了解这些基本的设计模式,慢慢学着去应用!如果文中有不对之处,请在评论中指出,我会在明确之后更正文章内容!

(0)

相关推荐

  • 学习php设计模式 php实现单例模式(singleton)

    保证一个类仅有一个实例,并且提供一个访问它的全局访问点. 单例模式有三个特点: 1.一个类只有一个实例 2.它必须自行创建这个实例 3.必须自行向整个系统提供这个实例 一.单例模式结构图 二.单例模式中主要角色 Singleton 定义一个Instance操作,允许客户访问它的唯一实例.Instance是一个类方法.负责创建它的唯一的实例. 三.单例模式的优点 1.对唯一实例的受控访问 2.缩小命名空间 单例模式是对全局变量的一种改进.它避免了那些存储唯一实例的全局变量污染命名空间 3.允许对操

  • php设计模式 Strategy(策略模式)

    抽象策略(Strategy)角色:定义所有支持的算法的公共接口.通常是以一个接口或抽象来实现.Context使用这个接口来调用其ConcreteStrategy定义的算法. 具体策略(ConcreteStrategy)角色:以Strategy接口实现某具体算法. 环境(Context)角色:持有一个Strategy类的引用,用一个ConcreteStrategy对象来配置 核心代码 <?php interface Strategy { // 抽象策略角色,以接口实现 public functio

  • PHP最常用的2种设计模式工厂模式和单例模式介绍

    1.工厂模式 主要作用是降低耦合度. 复制代码 代码如下: abstract class Operation{ abstract public function getValue($num1,$num2); public function getAttr(){ return 1; } } class Add extends Operation{ public function getValue($num1, $num2){ return $num1+$num2; } } class Sub ex

  • php设计模式 DAO(数据访问对象模式)

    复制代码 代码如下: <?php /** * 数据访问对象(Data Access Object) 示例 * * @create_date: 2010-01-04 */ class BaseDAO { var $_db = null; var $_table = null; function BaseDAO($config) { $this->_db = new MysqlDB(); // 这里的不能进行操作 } /** * 获取处理 * * @param array $filter // 过

  • php单态设计模式(单例模式)实例

    单态设计模式也叫单例模式: 1.单态设计模式含义: 单态模式的主要作用是保证在面向对象编程设计中,一个类只能有一个实例对象存在.作为对象的创建模式,单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统全局地提供这个实例.它不会创建实例副本,而是会向单例类内部存储的实例返回一个引用. 2.单台模式的三个关键点: ① 需要一个保存类的唯一实例的静态成员变量: ②构造函数和克隆函数必须声明为私有的,防止外部程序new类从而失去单例模式的意义: ③必须提供一个访问这个实例的公共的静态方法(通常为

  • php设计模式 Facade(外观模式)

    模式定义:外观模式(Facade Pattern):外部与一个子系统的通信必须通过一个统一的外观对象进行,为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用.外观模式又称为门面模式,它是一种对象结构型模式. 模式结构: 外观模式的就是让client客户端以一种简单的方式来调用比较复杂的系统,来完成一件事情. Subsystem: 复制代码 代码如下: class car { public function start() { print_r("

  • php简单实现单态设计模式的方法分析

    本文实例讲述了php简单实现单态设计模式的方法.分享给大家供大家参考,具体如下: 单态设计模式通常包含以下三点: · 一个私有的 构造方法:(确保用户无法通过创建对象对其进行实例化) · 一个公有的 静态的 方法:(负责对其本身进行实例化) · 一个私有的 静态的 属性:(用于保存仅有的一个实例化对象) <?php class singleTon{ //用于保存仅有的一个实例化对象 private static $Instance=NULL; //构造方法 使用private 封装后 则只能在类

  • php设计模式 Singleton(单例模式)

    复制代码 代码如下: <?php /** * 单例模式 * * 保证一个类仅有一个实例,并提供一个访问它的全局访问点 * */ class Singleton { static private $_instance = null; private function __construct() { } static public function getInstance() { if(is_null(self::$_instance)) { self::$_instance = new Singl

  • PHP设计模式之工厂模式与单例模式

    本文实例讲述了PHP设计模式之工厂模式与单例模式实现方法.分享给大家供大家参考,具体如下: 设计模式简单说应对某类问题而设计的解决方式 工厂模式:应对需求创建相应的对象 class factory{ function __construct($name){ if(file_exists('./'.$name.'.class.php')){ return new $name; }else{ die('not exist'); } } } 单例模式:只创建一个对象的实例,不允许再创建实例,节约资源(

  • php设计模式 Interpreter(解释器模式)

    复制代码 代码如下: <?php /** * 解释器 示例 * * @create_date: 2010-01-04 */ class Expression { function interpreter($str) { return $str; } } class ExpressionNum extends Expression { function interpreter($str) { switch($str) { case "0": return "零"

  • php设计模式 Template (模板模式)

    继承关系由于自身的缺陷,被专家们扣上了"罪恶"的帽子."使用委派关系代替继承关系","尽量使用接口实现而不是抽象类继承"等等专家警告,让我们这些菜鸟对继承"另眼相看".其实,继承还是有很多自身的优点所在.只是被大家滥用的似乎缺点更加明显了.合理的利用继承关系,还是能对你的系统设计起到很好的作用的.而模板方法模式就是其中的一个使用范例. GOF给模板方法(Template Method)模式定义一个操作中的算法的骨架,而将一些步

  • php设计模式 Proxy (代理模式)

    代理,指的就是一个角色代表另一个角色采取行动,就象生活中,一个红酒厂商,是不会直接把红酒零售客户的,都是通过代理来完成他的销售业务.而客户,也不用为了喝红酒而到处找工厂,他只要找到厂商在当地的代理就行了,具体红酒工厂在那里,客户不用关心,代理会帮他处理. 代理模式,就是给某一对象提供代理对象,并由代理对象控制具体对象的引用. 代理模式涉及的角色: 抽象主题角色,声明了代理主题和真实主题的公共接口,使任何需要真实主题的地方都能用代理主题代替. 代理主题角色,含有真实主题的引用,从而可以在任何时候操

随机推荐