深入PHP面向对象、模式与实践——让面向对象编程更加灵活的模式(2)
来源:互联网 发布:mac打开远程桌面 编辑:程序博客网 时间:2024/05/16 05:36
装饰模式
组合模式帮助我们聚合组件,而装饰模式则使用类似结构来帮助我们改变具体组件的功能。
装饰模式使用组合和委托而不是只使用继承来解决功能变化的问题。实际上,Decorator类会持有另外一个类的实例。Decorator对象会实现与被调用对象的方法相对应的类方法。用这种办法可以在运行时创建一系列的Decorator对象。
abstract class Tile{ abstract function getWealthFactor();}class Plains extends Tile{ private $wealthfactor = 2; function getWealthFactor() { return $this->wealthfactor; }}abstract class TileDecorator extends Tile{ protected $tile; function __construct(Tile $tile) { $this->tile = $this; }}class DiamondDecorator extends TileDecorator{ function getWealthFactor() { return $this->tile->getWealthFactor() + 2; }}class PollutionDecorator extends TileDecorator{ function getWealthFactor() { return $this->tile->getWealthFactor() - 4; }}$tile = new Plains();print $tile->getWealthFactor();//2$tile = new DiamondDecorator(new Plains());print $tile->getWealthFactor();//4$tile = new PollutionDecorator(new DiamondDecorator(new Plains()));print $tile->getWealthFactor();//0
通过像这样使用组合和委托,可以在运行时轻松地合并对象。因为模式中所有对象都扩展自Tile,所以客户端代码并不需要知道内部是如何合并的。
本例的类图如下:
这样的模型极具扩展性。我们可以非常轻松地添加新的装饰器或新的组件。通过使用大量装饰器,我们可以在运行时创建极为灵活的结构。
装饰模式建立的管道对于创建过滤器非常有用。客户端程序员可将核心组件与装饰对象合并,从而对核心方法进行过滤、缓冲、压缩等操作。下面是一个使用装饰模式的web请求实例:
class RequestHelper{}abstract class ProcessRequest{ abstract function process(RequestHelper $req);}class MainProcess extends ProcessRequest{ function process(RequestHelper $req) { print __CLASS__ . ":doing something useful with request\n"; }}abstract class DecorateProcess extends ProcessRequest{ protected $processrequest; function __construct(ProcessRequest $pr) { $this->processrequest = $pr; }}class LogRequest extends DecorateProcess{ function process(RequestHelper $req) { print __CLASS__ . ":logging request\n"; $this->processrequest->process($req); }}class AuthenticateRequest extends DecorateProcess{ function process(RequestHelper $req) { print __CLASS__ . ":authenticating request\n"; $this->processrequest->process($req); }}class StructureRequest extends DecorateProcess{ function process(RequestHelper $req) { print __CLASS__ . ":structuring request\n"; $this->processrequest->process($req); }}$process = new AuthenticateRequest(new StructureRequest(new LogRequest(new MainProcess())));$process->process(new RequestHelper());
一定要记住:组合和继承通常都是同时使用的。因为装饰对象作为子对象的包装,所以保持基类中的方法尽可能少是很重要的。如果一个基类具有大量的特性,那么装饰对象不得不为它们包装的对象的所有public方法加上委托。你可以用一个抽象的装饰类来实现,不过这仍旧会带来耦合,并可能导致bug的出现。
1 0
- 深入PHP面向对象、模式与实践——让面向对象编程更加灵活的模式(2)
- 深入PHP面向对象、模式与实践——让面向对象编程更加灵活的模式(3)
- 六. PHP模式设计----让面向对象编程更加灵活的模式
- 深入PHP面向对象、模式与实践——对象
- 面向对象设计和过程式编程(6.2)《深入PHP:面向对象、模式与实践》
- 深入PHP面向对象、模式与实践——对象工具(2)
- 深入PHP面向对象、模式与实践——生成对象(2)
- 深入 PHP 面向对象、模式与实践
- 深入 PHP 面向对象、模式与实践
- 深入php面向对象、模式与实践
- 深入PHP面向对象、模式与实践——模式原则(2)
- 深入PHP面向对象、模式与实践——企业模式(2)
- 深入PHP面向对象、模式与实践——高级特性(2)
- 深入PHP面向对象、模式与实践——执行及描述任务(2)
- 【读书笔记-重构与模式】 组合模式-让面向对象更加灵活
- 深入PHP面向对象、模式与实践——对象工具(1)
- 深入PHP面向对象、模式与实践——生成对象(1)
- 深入PHP面向对象、模式与实践——生成对象(3)
- Matlab Robitic Toolbox学习笔记Day2
- 关于利用js编写网页程序的心得或碰到的错误点1
- 机器学习综述
- 直播市场规模有限,差异化竞争成行业必然趋势
- Java优先级队列
- 深入PHP面向对象、模式与实践——让面向对象编程更加灵活的模式(2)
- 情景linux--如何获取一个UUID?
- 关于播放受损视频的问题
- 转 eclipse代码自动提示设置、如何配置eclipse的代码自动提示功能?
- 蓝桥杯 寒假作业
- VI编辑器的操作模式
- "ceph"这个命令无法使用
- JUnit单元测试框架的使用
- 怎样进行调试