前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >PHP设计模式之装饰器模式定义与用法详解

PHP设计模式之装饰器模式定义与用法详解

作者头像
用户8660814
修改于 2021-07-13 03:29:11
修改于 2021-07-13 03:29:11
4470
举报

本文实例讲述了PHP设计模式之装饰器模式定义与用法。分享给大家供大家参考,具体如下:

什么是装饰器模式

作为一种结构型模式, 装饰器(Decorator)模式就是对一个已有结构增加"装饰".

适配器模式, 是为现在有结构增加的是一个适配器类,.将一个类的接口,转换成客户期望的另外一个接口.适配器让原本接口不兼容的类可以很好的合作.

装饰器模式是将一个对象包装起来以增强新的行为和责任.装饰器也称为包装器(类似于适配器)

有些设计设计模式包含一个抽象类,而且该抽象类还继承了另一个抽象类,这种设计模式为数不多,而装饰器就是其中之一.

什么时候使用装饰器模式

基本说来, 如果想为现有对象增加新功能而不想影响其他对象, 就可以使用装饰器模式.如果你好不容易为客户创建了一个网站格式, 主要组件的工作都很完美, 客户请求新功能时, 你肯定不希望推翻重来, 再重新创建网站. 例如, 假设你已经构建了客户原先请求的组件, 之后客户又有了新的需求, 希望在网站中包含视频功能. 你不用重写原先的组件, 只需要"装饰"现有组件, 为它们增加视频功能. 这样即可以保持原来的功能,还可以增加新功能.

有些项目可能有时需要装饰, 而有时不希望装饰, 这些项目体现了装饰器设计模式的另一个重要特性.假设你的基本网站开发模式可以满足大多数客户的要求. 不过, 胡些客户还希望有一些特定的功能来满足他们的需求. 并不是所有人都希望或需要这些额外的功能. 作为开发人员, 你希望你创建的网站能满足客户的业务目标. 所以需要提供"本地化"(customerization)特性, 即针对特定业务提供的特性. 利用装饰器模式, 不仅能提供核心功能, 还可以用客户要求的特有功能"装饰"这些核心功能.

简单的装饰器例子

一个web开发企业,计划建立一个基本网站,并提供一些增强功能. 不过,web开发人员知道, 尽管这个基本计划适用于大多数客户, 但客户以后很可能还希望进一步提升, 利用装饰器模式, 可以很容易地增加多个具体装饰器,另外由于你能选择要增加的装饰器, 所以企业不仅能控制功能, 还可以控制项目的成本 .

Component接口

Component参与者是一个接口, 在这里, 它是一个抽象类IComponent. 这个抽象类只有一个属性$site, 另外有两个抽象方法getSite()和getPrice().Component参与者具体为具体组件和Decorator参与者抽象类建立接口:

IComponent.php

<?php

abstract class IComponent

{

protected $site;

abstract public function getSite();

abstract public function getPrice();

}

Decorator接口

这个例子中的装饰器接口可能会让你惊讶.这是一个抽象类,而且它还扩展了另一个抽象类! 这个类的作用就是维护组件接口(IComponent)的一个引用, 这是通过扩展IComponent完成的:

Decorator.php

<?php

abstract class Decorator extends IComponent

{

/*

任务是维护Component的引用

继承getSite()和getPrice()

因为仍然是抽象类,所以不需要实现父类任何一个抽象方法

*/

}

Decorator类的主要作用就是维护组件接口的一个引用.

在所有的装饰器模式实现中, 你会发现,具体组件和装饰顺都有相同的接口. 它们的实现可能不同, 另外除了基本接口的属性和方法外, 组件和装饰器可能还有额外的属性和方法.

具体组件

这个例子中只有一个具体组件,它生成一个网站名, 另外生成一个基本网站报价:

BasicSite.php

<?php

class BasicSite extends IComponent

{

public function __construct()

{

$this->site = "Basic Site";

}

public function getSite()

{

return $this->site;

}

public function getPrice()

{

return 1200;

}

}

两个抽象方法都使用直接赋值来实现, 不过灵活性并不体现在如何改变设置的值.实际上, 要通过增加装饰器值来改变"Basic Site"值.

具体装饰器

这个例子中的具体装饰器与具体组件有相同的接口.实际上, 它们是从Decorator抽象类(而不是IComponent类)继承了这个接口. 不过,要记住, Decorator所做的就是继承IComponent接口.

Maintenance.php

<?php

class Maintenance extends Decorato

{

public function __construct(IComponent $siteNow)

{

$this-&gt;site = $siteNow;

}

public function getSite()

{

$format = "<br /> Maintenance";

return $this-&gt;site-&gt;getSite() . $format;

}

public function getPrice()

{

return 950 + $this->site->getPrice();

}

}

这个装饰器Maintenance在改变了site的值, 还有包装的具体组件价格上还会增加它自己 的价格. 另个两个具体装饰器与Maintenance装饰器也类似

Video.php

<?php

class Video extends Decorato

{

public function __construct(IComponent $siteNow)

{

$this-&gt;site = $siteNow;

}

public function getSite()

{

$format = "<br /> Video";

return $this-&gt;site-&gt;getSite() . $format;

}

public function getPrice()

{

return 350 + $this->site->getPrice();

}

}

/

/DataBase.php

<?php

class DataBase extends Decorato

{

public function __construct(IComponent $siteNow)

{

$this-&gt;site = $siteNow;

}

public function getSite()

{

$format = "<br /> DataBase";

return $this-&gt;site-&gt;getSite() . $format;

}

public function getPrice()

{

return 800 + $this->site->getPrice();

}

}

测试这个应用时,可以看到,在基本的价格之上还会增加各个装饰器的价格.另外还能指定装饰器名的格式, 增加了两个空格,使之缩进

装饰器实现中最重要的元素之五就是构造函数, 要为构造函数提供一个组件类型. 由于这里只有一个具体组件, 所有装饰器的实例化都会使用这个组件. 使用多个组件时, 装饰器可以包装应用中的一部分或全部组件, 也可以不包装任何组件.

客户

Client类并不是这个设计模式的一部分, 但是正确使用Client类至关重要.每个装饰器在实例化时"包装"组件, 不过, 首先必须创建一个要包装的对象, 这里是BasicSite类实例

Client.php

<?php

function __autoload($class_name)

{

include $class_name . '.php';

}

class Client

{

private $basicSite;

public function __construct()

{

$this->basicSite = new BasicSite();

$this-&gt;basicSite = $this->WrapComponent($this->basicSite);

$siteShow = $this->basicSite->getSite();

$format = "&lt;br /&gt; &lt;strong&gt;Total= $";

$price = $this->basicSite->getPrice();

echo $siteShow . $format . $price . "</strong>";

}

private function WrapComponent(IComponent $component)

{

$component = new Maintenance($component);

$component = new Video($component);

$component = new DataBase($component);

return $component;

}

}

$worker = new Client();

wrapComponent()方法检查传入的BasicSite实例, 以确保参数有正确的数据类型(IComponent), 然后分别实例化3个装饰器, 对该实例对象进行装饰.

Basic Site

  Maintenance

  Video

  DataBase

  Total= $3300

适配器和装饰器模式都有另外一个名字"包装器"(wrapper)".

适配器可以"包装"一个对象, 创建一个与Adaptee兼容的接口, 而无须对它做任何修改.

装饰器也可以"包装"一个组件对象, /

/这样就能为这个已胡的组件增加职责, 而无须对它做任何修改.

下面的代码展示了Client如何将组件对象($component)包装在装饰器(Maintence)中:

$component = new Maintenance($component);

类似于"接口", 在计算机编程中用到"包装器"时, 不同的上下文会有不同的用法和含义. 一般来讲, 在设计模式中使用"包装器"是为了处理接口的不兼容, 或者希望为组件增加功能,包装器就表示用来减少不兼容性的策略.

希望本文所述对大家PHP程序设计有所帮助。

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
PHP设计模式之装饰器模式
工厂模式告一段落,我们来研究其他一些模式。不知道各位大佬有没有尝试过女装?据说女装大佬程序员很多哟。其实,今天的装饰器模式就和化妆这件事很像。相信如果有程序媛MM在的话,马上就能和你讲清楚这个设计模式。
硬核项目经理
2019/08/06
7870
PHP设计模式之装饰器模式
【地铁上的设计模式】--结构型模式:装饰器模式
装饰器模式是一种结构型设计模式,它允许你通过将对象放入包含行为的特殊封装对象中来为原对象添加新的行为,同时又不改变原有对象的结构。装饰器模式中,包装器对象和被包装对象实现了相同的接口,因此客户端无需知道具体的实现细节,只需通过接口即可使用包装器对象。这种模式能够让你在不修改现有代码的情况下,为已有对象增加新的功能。
喵叔
2023/05/03
2920
重温设计模式 --- 装饰器模式
装饰器模式是一种结构型设计模式,它允许在不改变原始对象的情况下,通过将其包装在一个装饰器对象中,来动态地添加额外的功能。
Niuery Diary
2023/10/22
1480
重温设计模式 --- 装饰器模式
PHP设计模式之适配器模式定义与用法详解
本文实例讲述了PHP设计模式之适配器模式定义与用法。分享给大家供大家参考,具体如下:
用户8660814
2021/07/13
3530
【php设计模式】装饰器模式
装饰器模式,顾名思义,就是对已经存在的某些类进行装饰,以此来扩展一些功能。其结构图如下:
码缘
2019/06/17
3390
【php设计模式】装饰器模式
PHP设计模式之原型模式定义与用法详解
本文实例讲述了PHP设计模式之原型模式定义与用法。分享给大家供大家参考,具体如下:
用户8660814
2021/07/13
3660
GoF 23种经典的设计模式——装饰器模式
装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。
Andromeda
2024/01/21
650
「聊设计模式」之装饰器模式(Decorator)
🏆本文收录于《聊设计模式》专栏,专门攻坚指数级提升,助你一臂之力,带你早日登顶🚀,欢迎持续关注&&收藏&&订阅!
bug菌
2023/11/06
3871
「聊设计模式」之装饰器模式(Decorator)
一文搞懂设计模式—装饰器模式
装饰器模式(Decorator Pattern)是一种结构型设计模式,它允许向现有对象添加新功能而不改变其结构。装饰器模式通过创建包装对象(装饰器)来动态地扩展对象的行为,是继承的替代方案之一。
BookSea
2024/02/29
5780
一文搞懂设计模式—装饰器模式
Java设计模式-装饰器模式 理论代码相结合
上班族大多都有睡懒觉的习惯,每天早上上班时间都很紧张,于是很多人为了多睡一会,就会用方便的方式解决早餐问题。有些人早餐可能会吃煎饼,煎饼中可以加鸡蛋,也可以加香肠,但是不管怎么“加码”,都还是一个煎饼。在现实生活中,常常需要对现有产品增加新的功能或美化其外观,如房子装修、相片加相框等,都是装饰器模式。在我们自己行业就是这个东西得加需求啦
宁在春
2022/10/31
4040
Java设计模式-装饰器模式 理论代码相结合
设计模式日记(Decorator)-装饰器模式
装饰器(Decorator)模式指在不改变现有对象结构的情况下,动态地给该对象增加一些职责(即增加其额外功能)的模式,它属于对象结构型模式。采用装饰模式扩展对象的功能比采用继承方式更加灵活;可以设计出多个不同的具体装饰类,创造出多个不同行为的组合。但是装饰模式增加了许多子类,如果过度使用会使程序变得很复杂。
六个核弹
2022/12/23
2400
设计模式之装饰器模式 Decorator 包装模式 wrapper 优点 缺点 使用场景 以及简化方法
首发原文地址:装饰器模式 引子 现实世界的装饰器模式 大家应该都吃过手抓饼,本文装饰器模式以手抓饼为模型展开简介 "老板,来一个手抓饼,  加个培根,  加个鸡蛋,多少钱?" 这句话会不会很耳熟,
noteless
2018/09/11
3.1K0
设计模式之装饰器模式 Decorator 包装模式 wrapper  优点 缺点 使用场景 以及简化方法
php设计模式(十一):装饰器模式(Decorator)
装饰器模式又称:装饰者模式、Wrappe、Decorator。装饰是一种结构型设计模式,允许你通过将对象放入包含行为的特殊封装对象中来为原对象绑定新的行为。
高久峰
2023/09/18
2210
php设计模式(十一):装饰器模式(Decorator)
详解设计模式:装饰器模式
装饰器模式(Decorator Pattern)也称为包装模式(Wrapper Pattern),是 GoF 的 23 种设计模式中的一种结构型设计模式。
栗筝i
2022/12/02
3860
详解设计模式:装饰器模式
php设计模式(十一):装饰器模式(Decorator)
装饰器模式又称:装饰者模式、Wrappe、Decorator。装饰是一种结构型设计模式,允许你通过将对象放入包含行为的特殊封装对象中来为原对象绑定新的行为。
陈大剩博客
2023/04/27
4750
php设计模式(十一):装饰器模式(Decorator)
设计模式(八)装饰器模式Decorator(结构型)
上面的类图看起来并不怎么坏,下面让我们再增加一些特性。表单验证阶段,你希望能够指出一个表单控制是否合法。你为非法控制使用的代码又一次继承其它组件,因此又需要产生大量的子类:
黄规速
2022/04/14
3830
设计模式(八)装饰器模式Decorator(结构型)
设计模式之装饰器模式
装饰器模式(Decorator Pattern)是一种结构型设计模式,它可以在不改变现有对象的结构的情况下,动态地给对象增加一些额外的功能。装饰器模式通过创建一个包装对象(即装饰器)来包裹真实对象,并在保持真实对象的接口不变的前提下,为其提供额外的功能。装饰器模式可以在运行时根据需要选择不同的装饰器来组合和修改对象的行为。
wayn
2023/09/12
2270
设计模式之装饰器模式
Java二十三种设计模式-装饰器模式(7/23)
装饰器模式(Decorator Pattern)是一种结构型设计模式,用于在不修改对象自身的基础上,通过添加额外的职责来扩展对象的功能。
正在走向自律
2024/12/18
1310
Java二十三种设计模式-装饰器模式(7/23)
【Java设计模式】014-装饰器模式
装饰器(Decorator)模式:指在不改变现有对象结构的情况下,动态地给该对象增加一些职责(即增加其额外功能)的模式,它属于对象结构型模式。
訾博ZiBo
2025/01/06
970
23种设计模式(三)--装饰器模式
我们都知道装饰, 元旦, 圣诞节, 我们都需要装饰, 渲染节日气氛. . 所谓装饰, 就是在原来的基础上加东西.
用户7798898
2021/06/24
4360
推荐阅读
相关推荐
PHP设计模式之装饰器模式
更多 >
领券
社区富文本编辑器全新改版!诚邀体验~
全新交互,全新视觉,新增快捷键、悬浮工具栏、高亮块等功能并同时优化现有功能,全面提升创作效率和体验
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文