PHP的设计模式(四)之原型模式、装饰器模式

分享于:2019-10-07 17:13:43


原型模式


原型模式(对象克隆以避免创建对象时的消耗) ,又称克隆模式。
1:与工厂模式类似,都是用来创建对象。 
2:与工厂模式的实现不同,原型模式是先创建好一个原型对象,然后通过clone原型对象来创建新的对象。这样就免去了类创建时重复的初始化操作。 
3:原型模式适用于大对象的创建,创建一个大对象需要很大的开销,如果每次new就会消耗很大,原型模式仅需要内存拷贝即可。


<?php
    // 人
    class Person {
        private $name;
        private $age;

        public function __construct($name, $age) {
            $this->name = $name;
            $this->age = $age;
        }

        public function showMyself() {
            echo "我是{$this->name}, 年龄{$this->age}" . PHP_EOL;
        }

        public function coding() {
            echo "我是一个码农, 我在用双手改变世界以及我的发际线..." . PHP_EOL;
        }

        public function reading() {
            echo "阅读是我快乐, 我爱阅读胜过爱左手..." . PHP_EOL;
        }

        public function fallInLove() {
            echo "神鬼狐仙, 风月无边...";
        }

        public function copy() {
            return clone($this);
        }
    }


    // 代码测试
    $tony = new Person("Tony", 26);
    $tony->showMyself();
    $tony->coding();

    $tony1 = $tony->copy();
    $tony1->showMyself();
    $tony1->reading();

    $tony2 = $tony->copy();
    $tony2->showMyself();
    $tony2->fallInLove();

结果:

我是Tony, 年龄26
我是一个码农, 我在用双手改变世界以及我的发际线...
我是Tony, 年龄26
阅读是我快乐, 我爱阅读胜过爱左手...
我是Tony, 年龄26
神鬼狐仙, 风月无边...


装饰器模式


1:装饰器模式,可以动态的添加修改类的功能 
2:一个类提供了一项功能,如果要在修改并添加额外的功能,传统的编程模式,需要写一个子类继承它,并重写实现类的方法 
3:使用装饰器模式,仅需要在运行时添加一个装饰器对象即可实现,可以实现最大额灵活性。


最常见的就是一些游戏开发商,通过去做一些装备,例如武器,衣服,鞋子,戒指等等,来吸引玩家购买,穿在身上不仅好看,还带有额外属性。

这个例子是典型装饰器模式的应用,特点是在不影响其他类的情况下动态添加其它具体装备类。

<?php

/** 构件接口类      
 *  interface IComponent          
 */    
interface IComponent{
  function Display();
}

/** 人物类     
 *  Person         
 */    
Class Person implements IComponent{
    private $name;
    function __construct($name){
       $this->name = $name;
    }
    function Display(){
       echo "{$this->name}当前装备:";
    }
}

/** 装备类    
 *  Equipment         
 */  
Class Equipment implements IComponent{
    protected $component;
    function Decorator(IComponent $component)  
    {
        // 动态添加  
        $this->component = $component;
    }
    function Display(){
        if(!empty($this->component)){
           $this->component->Display();
        }
    }
}

/** 具体装备 武器类    
 *  Weapon        
 */  
Class Weapon extends Equipment{
    function Display(){
        parent::Display();
        echo "龙泉剑 ";
    }
}

/** 具体装备 戒指类    
 *  Ring        
 */  
Class Ring extends Equipment{
    function Display(){
        parent::Display();
        echo "复活戒指 ";
    }
}

/** 具体装备 鞋子类    
 *  Shoes       
 */  
Class Shoes extends Equipment{
    function Display(){
        parent::Display();
        echo "御风履 ";
    }
}
// 如果需要可以继续添加具体的装备 腰带 裤子 手镯
<?php
// 装饰器模式 index.php  
header("Content-Type:text/html;charset=utf-8");
require_once "Decorator.php";

// 创建人物  
$people = new Person("战士");
// 武器  
$Weapon = new Weapon();
// 戒指  
$Ring = new Ring();
// 鞋子  
$Shoes = new Shoes();

// 动态添加函数  
$Weapon->Decorator($people);
$Ring->Decorator($Weapon);
$Shoes->Decorator($Ring);

// 显示  
$Shoes->Display();


输出结果:

战士当前装备:龙泉剑 复活戒指 御风履

装饰器模式的优点:


1、使用装饰器模式来实现扩展比继承更加灵活,它可以在不需要创造更多子类的情况下,将对象的功能加以扩展。

2、可以用不同的装饰器进行多重装饰,装饰的顺序不同,可能产生不同的效果。

3、装饰类和被装饰类可以独立发展,不会相互耦合;装饰器模式相当于是继承的一个替代模式。


装饰器模式和中间件思想还是有些颇有相似之处。    AOP 面向切面编程就是装饰器模式的一种实现。

PHP进阶之中间件代码实现