装饰(Decorator)模式

装饰模式可以在不使用创造更多子类的情况下,将对象的功能加以扩展。是继承关系的一个替代方案。

 

装饰模式的结构

抽象构件(Component)角色:给出一个抽象接口,以规范准备接收附加功能的对象。

具体构件(Concrete Component)角色:定义一个将要接收附加功能的类。

具体装饰(Concrete Decorator)角色:负责给构件对象附加的功能。

 

 

应用案例

    场景 : 文章功能拓展
    文章类已经写好,有个取文章内容的功能.
    
    class article{
        public function geiContent(){
            echo '取出文章内容';
        }
    }
    
    后期需要给它拓展些功能.
    编辑部说: 给文章开头加个"导读".
    审核部说: 给文章加个过滤关键字功能.
    市场部说: 给文章末尾加个广告.
    
    我们可能会这么写
    class article{
        //取文章
        public function getContent(){echo '取出文章';}
        //加导读
        public function addIntro(){echo '加导读';}
        //加过滤
        public function addFilter(){ echo '过滤关键词';}
        //加广告
        public function addAdve(){echo '加广告';}
    }
    不好之处 : 如果我们直接在article类里添加功能,那就是修改了这个类.此时违反了面向对象的"开闭原则".
    
    
    为了避免违反开闭原则我们就拆分开,一个功能一个类.然后继承一下不就添加好了吗?
    //文章类
    class article{}
    //导读类
    class intro extends article{}  //此时文章的子类,已经附加了导读功能.
    //过滤类
    class filter extends intro{}   //此时文章的子类,已经附加了导读和过滤
    //广告类
    class adve   extends filter{}  //此时文章的子类,已经附加了导读和过滤,广告.
    
    不好之处 : 拓展功能虽然完成,也没违反开闭原则.但是继承的层次太多了.影响效率.

 

 

 

案例实现

<?php

   //文章接口  抽象构件(Component)角色
   interface article{
      public function decorator();
   }
   
   //文章类   
   class baseArticle implements article{
     public $content = '文章内容';
     //装饰方法(文章类没装饰任何方法,只返回原始文章)
     public function decorator(){
       return $this->content;
     }
   }
   
   //装饰类  具体构件(Concrete Component)角色
   class decoratorArticle implements article{
      public $article = null;   //文章对象
      public function __construct($article){
          $this->article = $article;
       }
      public function decorator(){
        return $this->article->decorator();
      }
   }
   
   //导读类 (装饰角色)
   class introArticle extends decoratorArticle{
       public function decorator(){
        return '导读内容' . parent::decorator();
      }
   }
   
    //过滤类 (装饰角色)
   class filterArticle extends decoratorArticle{
       public function decorator(){
        return '过滤内容---' . parent::decorator();
      }
   }   
   
   //广告类 (装饰角色)
   class adveArticle extends decoratorArticle{
       public function decorator(){
        return '加个广告---' . parent::decorator();
      }
   } 

//原始文章 
$base = new baseArticle();  
//加个过滤 
$filter = new filterArticle($base);  
//加个广告
$adve = new adveArticle($filter);
//加个导读
$intro = new introArticle($adve);

echo $intro->decorator();       
?>

 

posted @ 2014-03-09 15:11  tlijian1989  阅读(123)  评论(0编辑  收藏  举报