• 售前

  • 售后

热门帖子
入门百科

PHP设计模式之装饰器模式界说与用法详解

[复制链接]
Creseda 显示全部楼层 发表于 2021-10-25 19:03:40 |阅读模式 打印 上一主题 下一主题
本文实例陈诉了PHP计划模式之装饰器模式界说与用法。分享给大家供大家参考,详细如下:
什么是装饰器模式
作为一种结构型模式, 装饰器(Decorator)模式就是对一个已有结构增长"装饰".
适配器模式, 是为现在有结构增长的是一个适配器类,.将一个类的接口,转换成客户期望的别的一个接口.适配器让原本接口不兼容的类可以很好的互助.
装饰器模式是将一个对象包装起来以增强新的行为和责任.装饰器也称为包装器(类似于适配器)
有些计划计划模式包罗一个抽象类,而且该抽象类还继续了另一个抽象类,这种计划模式为数不多,而装饰器就是其中之一.
什么时间利用装饰器模式
根本说来, 假如想为现有对象增长新功能而不想影响其他对象, 就可以利用装饰器模式.假如你好不容易为客户创建了一个网站格式, 重要组件的工作都很完满, 客户哀求新功能时, 你肯定不渴望颠覆重来, 再重新创建网站. 例如, 假设你已经构建了客户原先哀求的组件, 之后客户又有了新的需求, 渴望在网站中包罗视频功能. 你不消重写原先的组件, 只需要"装饰"现有组件, 为它们增长视频功能. 如许即可以保持原来的功能,还可以增长新功能.
有些项目可能有时需要装饰, 而有时不渴望装饰, 这些项目表现了装饰器计划模式的另一个紧张特性.假设你的根本网站开发模式可以满意大多数客户的要求. 不外, 胡些客户还渴望有一些特定的功能来满意他们的需求. 并不是全部人都渴望或需要这些额外的功能. 作为开发人员, 你渴望你创建的网站能满意客户的业务目标. 所以需要提供"当地化"(customerization)特性, 即针对特定业务提供的特性. 利用装饰器模式, 不但能提供核心功能, 还可以用客户要求的特有功能"装饰"这些核心功能.
简单的装饰器例子
一个web开发企业,筹划创建一个根本网站,并提供一些增强功能. 不外,web开发人员知道, 只管这个根本筹划适用于大多数客户, 但客户以后很可能还渴望进一步提升, 利用装饰器模式, 可以很容易地增长多个详细装饰器,别的由于你能选择要增长的装饰器, 所以企业不但能控制功能, 还可以控制项目标本钱 .
Component接口
Component参与者是一个接口, 在这里, 它是一个抽象类IComponent. 这个抽象类只有一个属性$site, 别的有两个抽象方法
  1. getSite()
复制代码
  1. getPrice().Component
复制代码
参与者详细为详细组件和Decorator参与者抽象类创建接口:
IComponent.php
  1. <?php
  2. abstract class IComponent
  3. {
  4.   protected $site;
  5.   abstract public function getSite();
  6.   abstract public function getPrice();
  7. }
复制代码
Decorator接口
这个例子中的装饰器接口可能会让你惊讶.这是一个抽象类,而且它还扩展了另一个抽象类! 这个类的作用就是维护组件接口(IComponent)的一个引用, 这是通过扩展IComponent完成的:
Decorator.php
  1. <?php
  2. abstract class Decorator extends IComponent
  3. {
  4.   /*
  5.   任务是维护Component的引用
  6.   继承getSite()和getPrice()
  7.   因为仍然是抽象类,所以不需要实现父类任何一个抽象方法
  8.   */
  9. }
复制代码
Decorator类的重要作用就是维护组件接口的一个引用.
在全部的装饰器模式实现中, 你会发现,详细组件和装饰顺都有相同的接口. 它们的实现可能差别, 别的除了根本接口的属性和方法外, 组件和装饰器可能另有额外的属性和方法.
详细组件
这个例子中只有一个详细组件,它天生一个网站名, 别的天生一个根本网站报价:
BasicSite.php
  1. <?php
  2. class BasicSite extends IComponent
  3. {
  4.   public function __construct()
  5.   {
  6.     $this->site = "Basic Site";
  7.   }
  8.   public function getSite()
  9.   {
  10.     return $this->site;
  11.   }
  12.   public function getPrice()
  13.   {
  14.     return 1200;
  15.   }
  16. }
复制代码
两个抽象方法都利用直接赋值来实现, 不外灵活性并不表现在如何改变设置的值.现实上, 要通过增长装饰器值来改变"Basic Site"值.
详细装饰器
这个例子中的详细装饰器与详细组件有相同的接口.现实上, 它们是从Decorator抽象类(而不是IComponent类)继续了这个接口. 不外,要记取, Decorator所做的就是继续IComponent接口.
Maintenance.php
  1. <?php
  2. class Maintenance extends Decorator
  3. {
  4.   public function __construct(IComponent $siteNow)
  5.   {
  6.     $this->site = $siteNow;
  7.   }
  8.   public function getSite()
  9.   {
  10.     $format = "<br /> Maintenance";
  11.     return $this->site->getSite() . $format;
  12.   }
  13.   public function getPrice()
  14.   {
  15.     return 950 + $this->site->getPrice();
  16.   }
  17. }
复制代码
这个装饰器Maintenance在改变了site的值, 另有包装的详细组件代价上还会增长它自己 的代价. 另个两个详细装饰器与Maintenance装饰器也类似
Video.php
  1. <?php
  2. class Video extends Decorator
  3. {
  4.   public function __construct(IComponent $siteNow)
  5.   {
  6.     $this->site = $siteNow;
  7.   }
  8.   public function getSite()
  9.   {
  10.     $format = "<br /> Video";
  11.     return $this->site->getSite() . $format;
  12.   }
  13.   public function getPrice()
  14.   {
  15.     return 350 + $this->site->getPrice();
  16.   }
  17. }
复制代码
DataBase.php
  1. <?php
  2. class DataBase extends Decorator
  3. {
  4.   public function __construct(IComponent $siteNow)
  5.   {
  6.     $this->site = $siteNow;
  7.   }
  8.   public function getSite()
  9.   {
  10.     $format = "<br /> DataBase";
  11.     return $this->site->getSite() . $format;
  12.   }
  13.   public function getPrice()
  14.   {
  15.     return 800 + $this->site->getPrice();
  16.   }
  17. }
复制代码
测试这个应用时,可以看到,在根本的代价之上还会增长各个装饰器的代价.别的还能指定装饰器名的格式, 增长了两个空格,使之缩进
装饰器实现中最紧张的元素之五就是构造函数, 要为构造函数提供一个组件类型. 由于这里只有一个详细组件, 全部装饰器的实例化都会利用这个组件. 利用多个组件时, 装饰器可以包装应用中的一部门或全部组件, 也可以不包装任何组件.
客户
Client类并不是这个计划模式的一部门, 但是正确利用Client类至关紧张.每个装饰器在实例化时"包装"组件, 不外, 起首必须创建一个要包装的对象, 这里是BasicSite类实例
Client.php
  1. <?php
  2. function __autoload($class_name)
  3. {
  4.   include $class_name . '.php';
  5. }
  6. class Client
  7. {
  8.   private $basicSite;
  9.   public function __construct()
  10.   {
  11.     $this->basicSite = new BasicSite();
  12.     $this->basicSite = $this->WrapComponent($this->basicSite);
  13.     $siteShow = $this->basicSite->getSite();
  14.     $format = "<br /> <strong>Total= $";
  15.     $price = $this->basicSite->getPrice();
  16.     echo $siteShow . $format . $price . "</strong>";
  17.   }
  18.   private function WrapComponent(IComponent $component)
  19.   {
  20.     $component = new Maintenance($component);
  21.     $component = new Video($component);
  22.     $component = new DataBase($component);
  23.     return $component;
  24.   }
  25. }
  26. $worker = new Client();
复制代码
  1. wrapComponent()
复制代码
方法查抄传入的BasicSite实例, 以确保参数有正确的数据类型(IComponent), 然后分别实例化3个装饰器, 对该实例对象举行装饰.
Basic Site
  Maintenance
  Video
  DataBase
  Total= $3300

适配器和装饰器模式都有别的一个名字"包装器"(wrapper)".
适配器可以"包装"一个对象, 创建一个与Adaptee兼容的接口, 而无须对它做任何修改.
装饰器也可以"包装"一个组件对象, 如许就能为这个已胡的组件增长职责, 而无须对它做任何修改.
下面的代码展示了Client如何将组件对象($component)包装在装饰器(Maintence)中:
  1. $component = new Maintenance($component);
复制代码
类似于"接口", 在计算机编程中用到"包装器"时, 差别的上下文会有差别的用法和寄义. 一样平常来讲, 在计划模式中利用"包装器"是为了处置惩罚接口的不兼容, 大概渴望为组件增长功能,包装器就表现用来减少不兼容性的计谋.
更多关于PHP相干内容感爱好的读者可检察本站专题:《php面向对象程序计划入门教程》、《PHP根本语法入门教程》、《PHP数组(Array)操作技巧大全》、《php字符串(string)用法总结》、《php+mysql数据库操作入门教程》及《php常见数据库操作技巧汇总》
渴望本文所述对大家PHP程序计划有所帮助。

帖子地址: 

回复

使用道具 举报

分享
推广
火星云矿 | 预约S19Pro,享500抵1000!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

草根技术分享(草根吧)是全球知名中文IT技术交流平台,创建于2021年,包含原创博客、精品问答、职业培训、技术社区、资源下载等产品服务,提供原创、优质、完整内容的专业IT技术开发社区。
  • 官方手机版

  • 微信公众号

  • 商务合作