PHP学习心得


装饰器模式

<h3>装饰器模式(Decorator Pattern)</h3> <ul> <li>允许向一个已有的对象添加新的功能或部分内容,同时又不改变其结构。是作为现有的类的一个包装。</li> </ul> <h3>为什么需要装饰器模式:</h3> <ul> <li>要对一个已有的对象添加新功能,又不想修改它原来的结构。</li> <li>使用子类继承的方法去实现添加新功能,会不可避免地出现子类过多,继承链很长的情况。而且不少书籍都规劝我们竭力保持一个对象的父与子关系不超过3个。</li> <li>装饰器模式,可以提供对对象内容快速非侵入式地修改。</li> </ul> <h3>简单实例</h3> <ul> <li>如果有一个游戏角色,他原来就是默认穿一件长衫。现在游戏改进了,觉得这个角色,除了穿一件长衫前,还可以在里面穿一件袍子,或是一件球衣。在外面穿一套盔甲或是宇航服。</li> </ul> <h2>代码示例</h2> <pre><code class="language-PHP">&lt;?php /*游戏原来的角色类 class Person{ public function clothes(){ echo "长衫".PHP_EOL; } } */ //装饰器接口 interface Decorator { public function beforeDraw(); public function afterDraw(); } //具体装饰器1-宇航员装饰 class AstronautDecorator implements Decorator { public function beforeDraw() { echo "穿上T恤".PHP_EOL; } function afterDraw() { echo "穿上宇航服".PHP_EOL; echo "穿戴完毕".PHP_EOL; } } //具体装饰器2-警察装饰 class PoliceDecorator implements Decorator{ public function beforeDraw() { echo "穿上警服".PHP_EOL; } function afterDraw() { echo "穿上防弹衣".PHP_EOL; echo "穿戴完毕".PHP_EOL; } } //被装饰者 class Person{ protected $decorators = array(); //存放装饰器 //添加装饰器 public function addDecorator(Decorator $decorator) { $this-&gt;decorators[] = $decorator; } //所有装饰器的穿长衫前方法调用 public function beforeDraw() { foreach($this-&gt;decorators as $decorator) { $decorator-&gt;beforeDraw(); } } //所有装饰器的穿长衫后方法调用 public function afterDraw() { $decorators = array_reverse($this-&gt;decorators); foreach($decorators as $decorator) { $decorator-&gt;afterDraw(); } } //装饰方法 public function clothes(){ $this-&gt;beforeDraw(); echo "穿上长衫".PHP_EOL; $this-&gt;afterDraw(); } } //警察装饰 $police = new Person; $police-&gt;addDecorator(new PoliceDecorator); $police-&gt;clothes(); //宇航员装饰 $astronaut = new Person; $astronaut-&gt;addDecorator(new AstronautDecorator); $astronaut-&gt;clothes(); //混搭风 $madman = new Person; $madman-&gt;addDecorator(new PoliceDecorator); $madman-&gt;addDecorator(new AstronautDecorator); $madman-&gt;clothes();</code></pre>

页面列表

ITEM_HTML