装饰(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(); ?>