您的位置:首页 > 编程语言 > PHP开发

浅谈php设计模式

2017-05-03 15:40 645 查看
PHP一共有五个设计模式,分别对应为:

1、命令链模式

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

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

[php]
view plain
copy

/**   
 * 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());  //<span style="font-family: 宋体;">new EvenValidator() 返回 </span><span style="font-family: 宋体;">EvenValidator实例化的对象 </span><span style="font-family: 宋体;">  
</span>$processor->process(array(1, 20, 18, 5, 0, 31, 42));   

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

2、策略模式

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

封装:把行为用接口封装起来,我们可以把那些经常变化的部分,从当前的类中单独取出来,用接口进行单独的封装。

互相替换:我们封装好了接口,通过指定不同的接口实现类进行算法的变化。

//如下

我们创建了一个超人类(duck)

还有一个基类接口类(FlyBehavior),定义了里面的一个fly()方法

建立了另外两个类FlyWithWings 和FlyWithNo 继承了FlyBehavior
类 ,FlyWithWings
和 FlyWithNo 分别重构了自己的 fly() 方法,

仿我们调用超人类(duck)时 通过调用setFlyBehavior()方法时就可以通过传不同的类,返回不同的对象.虽然他们后面调用的方法名一样.但是对象不同.

所以他们调用了不同的方法(相当于)

[php]
view plain
copy

<?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]
view plain
copy





<?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]
view plain
copy





<?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]
view plain
copy

<?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(); 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: