浅谈php设计模式

论坛 期权论坛 脚本     
已经匿名di用户   2022-4-26 16:02   2184   0

php一共有五个设计模式,分别对应为:

1、命令链模式

命令模式(Command)是封装一个通用操作的机制。它相当于程序中的:回调(callback)。(就是调用一个方法,方法实例化)

回调通常使用一个函数指针或数据结构如PHP中的字符串和数组实现,

/**  
 * The Command abstraction.  
 * In this case the implementation must return a result,  
 * sometimes it only has side effects.  
 */ 
interface Validator  
{  
    /**  
     * The method could have any parameters.  
     * @param mixed  
     * @return boolean  
     */ 
    public function isValid($value);  
}  
 
/**  
 * ConcreteCommand.  
 */ 
class MoreThanZeroValidator implements Validator  
{  
    public function isValid($value)  
    {  
        return $value > 0;  
    }  
}  
 
/**  
 * ConcreteCommand.  
 */ 
class EvenValidator implements Validator  
{  
    public function isValid($value)  
    {  
        return $value % 2 == 0;  
    }  
}  
 
/**  
 * The Invoker. An implementation could store more than one  
 * Validator if needed.  
 */ 
class ArrayProcessor  
{  
    protected $_rule;  
 
    public function __construct (Validator $rule)  
    {  
        $this->_rule = $rule;  
    }  
 
    public function process(array $numbers)  
    {  
        foreach ($numbers as $n) {  
            if ($this->_rule->IsValid($n)) {  
                echo $n, "\n";  
            }  
        }  
    }  
}  
 
// Client code  
$processor = new ArrayProcessor(new EvenValidator());  //new EvenValidator() 返回 EvenValidator实例化的对象 
$processor->process(array(1, 20, 18, 5, 0, 31, 42)); 

Command是在一个方法调用之上的抽象,它吸收了所有面向对象的好处:合成、继承和处理。




2、策略模式

定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。

封装:把行为用接口封装起来,我们可以把那些经常变化的部分,从当前的类中单独取出来,用接口进行单独的封装。
互相替换:我们封装好了接口,通过指定不同的接口实现类进行算法的变化。

//如下
我们创建了一个超人类(duck)
还有一个基类接口类( FlyBehavior),定义了里面的一个fly()方法
建立了另外两个类 FlyWithWings 和 FlyWithNo 继承了 FlyBehavior 类 ,FlyWithWings 和 FlyWithNo 分别重构了自己的 fly() 方法,
仿我们调用超人类(duck)时 通过调用 setFlyBehavior()方法时就可以通过传不同的类,返回不同的对象.虽然他们后面调用的方法名一样.但是对象不同.
所以他们调用了不同的方法(相当于)

<?php
interface FlyBehavior{
    public function fly();
}
 
class FlyWithWings implements FlyBehavior{
    public function fly(){
        echo "Fly With Wings \n";
    }
}
 
class FlyWithNo implements FlyBehavior{
    public function fly(){
        echo "Fly With No Wings \n";
    }
}
class Duck{
    private $_flyBehavior;
    public function performFly(){
        $this->_flyBehavior->fly();
    }
 
    public function setFlyBehavior(FlyBehavior $behavior){
        $this->_flyBehavior = $behavior;//返回传的那个类
    }
}
 
class RubberDuck extends Duck{
}
// Test Case
$duck = new RubberDuck();
 
/*  想让鸭子用翅膀飞行 */
$duck->setFlyBehavior(new FlyWithWings());
$duck->performFly();            
 
/*  想让鸭子不用翅膀飞行 */
$duck->setFlyBehavior(new FlyWithNo());
$duck->performFly();


3、工厂模式
只要是可以根据不同的参数生成不同的类实例,那么就符合工厂模式的设计思想。

<?php 
    //吃
    class Eat(){
        public static function eatNoodles(){
  return '吃面';
 }
    }
    
    //喝
    class Drink(){
 public static function drinkWater(){
  return '喝水';
 }    
    }  
    //吃喝拉撒
    class EatAndDrink(){
 public static function createObj($type){
  switch($type){
      case 'eat':
   return new Eat();
      case 'drink':
   return new Drink();   
  }
 } 
    }
 
    $obj = EatAndDrink::createObj('eat');
    var_dump($obj);
  
    
    $obj = EatAndDrink::createObj('drink');
    var_dump($obj);
?>
就如上面的代码一样,有一个单独的eat类和drink类,还有一个吃喝拉撒类,调用EatAndDrink类里面的createObj的方法来返回不同的实例化的对象


4、单元素模式(单例模式)

单元素模式(单例模式)特点:

单例模式按字面来看就是某一个类只有一个实例,这样做的好处还是很大的,比如说数据库的连接,我们只需要实例化一次,

不需要每次都去new了,这样极大的降低了资源的耗费。(如mysql连接)


单例类至少拥有以下三种公共元素:

必须拥有一个构造函数,并且必须被标记为private。
拥有一个保存类的实例的静态成员变量。
拥有一个访问这个实例的公共的静态方法

<?php
 
 class Mysql{
  //该属性用来保存实例
  private static $conn;
  //构造函数为private,防止创建对象
  private function __construct(){
   $this->conn = mysql_connect('localhost','root','');
  }
  //创建一个用来实例化对象的方法
  public static function getInstance(){
   if(!(self::$conn instanceof self)){
    self::$conn = new self;
   }
   return self::$conn;
  }
  //防止对象被复制
  public function __clone(){
   trigger_error('Clone is not allowed !');
  }
  
 }
 //只能这样取得实例,不能new 和 clone
 $mysql = Mysql::getInstance();
?>

5、观察者模式

观察者模式定义对象的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新!

主题和观察者都使用接口:观察者利用主题的接口向主题注册,而主题利用观察者接口通知观察者。这样可以让两者之间运作正常,又同时具有松耦合的优点! ——针对接口编程,不针对实现编程!

<?php
/**
 * 观察者模式
 * @author: Mac
 * @date: 2012/02/22
 */
 
 
class Paper{ /* 主题    */
    private $_observers = array();
 
    public function register($sub){ /*  注册观察者 */
        $this->_observers[] = $sub;
    }
 
     
    public function trigger(){  /*  外部统一访问    */
        if(!empty($this->_observers)){
            foreach($this->_observers as $observer){
                $observer->update();
            }
        }
    }
}
 
/**
 * 观察者要实现的接口
 */
interface Observerable{
    public function update();
}
 
class Subscriber implements Observerable{
    public function update(){
        echo "Callback\n";
    }
}
 

下面是测试代码

/*  测试    */
$paper = new Paper();
$paper->register(new Subscriber());
//$paper->register(new Subscriber1());
//$paper->register(new Subscriber2());
$paper->trigger();



分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:81
帖子:4969
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP