【设计模式】第六章:装饰器模式详解及应用案例

news/2024/11/24 11:30:29/

系列文章

【设计模式】七大设计原则
【设计模式】第一章:单例模式
【设计模式】第二章:工厂模式
【设计模式】第三章:建造者模式
【设计模式】第四章:原型模式
【设计模式】第五章:适配器模式
【设计模式】第六章:装饰器模式
【设计模式】第七章:代理模式
【设计模式】第八章:桥接模式
【设计模式】第九章:外观模式 / 门面模式
【设计模式】第十章:组合模式
【设计模式】第十一章:享元模式
【设计模式】第十二章:观察者模式
【设计模式】第十三章:模板方法模式
【设计模式】第十四章:策略模式
【设计模式】第十五章:责任链模式
【设计模式】第十六章:迭代器模式
【设计模式】第十七章:状态模式
【设计模式】第十八章:备忘录模式
【设计模式】第十九章:访问者模式
【设计模式】第二十章:解释器模式
【设计模式】第二十一章:命令模式
【设计模式】第二十二章:中介者模式


文章目录

  • 系列文章
  • 一、定义
  • 二、角色分类
  • 三、需求
  • 四、具体实现
    • UML图
    • 具体实现
        • **抽象装饰者(Decorator)**
  • 五、应用场景
  • 六、优缺点
    • 优点
    • 缺点


一、定义

摘自菜鸟教程:装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。

这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。


二、角色分类

装饰角色(Decorator)

一般是一个抽象类,继承或实现了抽象构件,在它的属性里有一个变量指向抽象构件

具体装饰角色(Concrete Decorator)

ConcreteDecoratorA和ConcreteDecoratorB是两个具体的装饰类,它们可以把基础构件装饰成新的对象。

客户(Client)

用来发起请求调用装饰方法的角色


三、需求

我们在日常的工作开发中一定会遇到一种场景:单点登录。意思就是用户只需要登录一次,就可以访问不同的服务,无需再次登录。

针对上面的场景,登录状态的维护就显得至关重要了。我们通常会使用cookie或者token来保存登录相关的信息,以便后续服务继续使用。但是还有一种情况就是:业务可能需要我们去限制某些用户对某些方法的访问权限,这就需要在单点登录的基础上再对用户进行一次权限认证。

假如我们现在有一个大型系统,其中有许多的子系统,其中系统A中有一个接口只允许管理员访问。那么我们如何在保证不破坏、不侵入代码的前提下完成这个需求呢,装饰器模式就可以帮我们解决这个问题。


四、具体实现

UML图

Image.png

具体实现

抽象装饰者(Decorator)

我们首先要定义一个抽象构件,并实现单点登录的接口对其增加一个扩展方法

public interface Decorator extends SSO {/*** 定义一个限制权限的方法*/boolean limit();
}

具体装饰者(Concrete Decorator)

public class DecoratorImpl implements Decorator {private SSO sso;public DecoratorImpl(SSO sso) {this.sso = sso;}/*** 实现限制权限的方法* @return*/@Overridepublic boolean limit() {// 获取用户信息User user = sso.getUser();// 判断该用户是否为管理员if("admin".equals(user.getType())) {System.out.println(user.getUserId() + " is admin");return true;}else {System.out.println(user.getUserId() + " is not admin");return false;}}/*** 实现原有的校验接口* @return boolean*/@Overridepublic boolean verify(){return sso.verify();}
}

然后我们就可以在SSO中想要拦截的地方调用该方法即可

客户(Client)

// 记录当前验证器
Decorator decorator = new DecoratorImpl(sso);
// 原有校验权限
if (decorator.verify()){// 自定义限制方法if (decorator.limit()) {System.out.println("执行方法");} else {System.out.println("无权限执行方法");}
} else {System.out.println("权限验证失败");
}

五、应用场景

以下部分内容摘自菜鸟教程

**意图:**动态的给一个对象添加一些额外的职责。就新增功能来说,装饰器模式会比生成子类更加灵活

**主要解决:**一般的,我们为了扩展一个类经常使用继承的方式来实现,由于继承为类引入静态特征,并且随着扩展 功能的增多,子类会很膨胀。

**何时使用:**在不想增加很多子类的情况下扩展类

**如何解决:**将具体功能职责划分,同时继承装饰器模式

关键代码:

  1. Component类充当抽象角色,不应该具体实现
  2. 修饰类引用和继承Component类,具体扩展类,重写父类方法

应用实例:

  1. 悟空有72变,当它变成庙宇后,他的本质还是一只猴子,但是他又有了庙宇的功能
  2. 不论一幅画有没有画框都可以被挂在墙上,但是通常都是有画框的,并且实际上是画框被挂在墙上。画可以被蒙上玻璃,撞到框子里;这时画、玻璃和画框形成了一个物体

适用场景:

  1. 扩展一个类的功能
  2. 动态增加功能、动态撤销

**注意事项:**可代替继承


六、优缺点

优点

装饰类和被装饰类可以独立发展,不会相互耦合,装饰器模式是继承的一个替代模式,装饰模式可以动态扩展一个实现类的功能

缺点

多层装饰比较复杂


http://www.ppmy.cn/news/773086.html

相关文章

macos可以升级到指定版本吗_如何升级mac系统版本?

展开全部 老版本mac如何升级系统,如果你的电脑是Mac的话,首先需要准备两636f70793231313335323631343130323136353331333431363533个工具:iOS13的固件和MobileDevice。在Mac上把MobileDevice安装好,把对应机型的iOS13固件包下载。…

iPhone升级系统 死机了怎么办

不少人升级系统结果遇到了死机、不能进入正常界面、白苹果的情况吧? 遇到这种问题,你可以这样解决: 白苹果 同时按下“电源键”和“Home键”,直到屏幕黑屏。屏幕黑屏时松开“电源键,继续按住“Home键”不放&#xf…

低版本MAC如何升级系统

1.进入苹果官网 2.点击技术支持 3.下面两个任意搜索其中一个进行升级会自动连接到APP Store 可完成低版本系统下载 ht206886 ht208202 4.下载完成后按步骤点击安装即可

苹果升级鸿蒙系统,华为正式官宣!首批鸿蒙系统正式版升级大名单出炉:这些用户有福了...

【5月31日讯】相信大家都知道,华为已经正式官宣将会在6月2日召开鸿蒙系统专场发布会,虽然目前华为方面并没有对外透露太多的消息,所以很多网友们都非常期待,华为鸿蒙OS系统专场发布会,能够带来更多惊喜和看点&#xff…

Docker学习笔记27

docker_swarm发布服务挂载本地卷: 存储卷应用: 持久化存储应用:(最大的一个需求点) 本地卷: [rootswarm-1 ~]# docker service create --replicas 1 --mount "typebind,source$PWD,target/abc"…

HarmonyOS学习路之开发篇—数据管理(对象关系映射数据库)

HarmonyOS对象关系映射(Object Relational Mapping,ORM)数据库是一款基于SQLite的数据库框架,屏蔽了底层SQLite数据库的SQL操作,针对实体和关系提供了增删改查等一系列的面向对象接口。应用开发者不必再去编写复杂的SQ…

scroll-view 横向滚动无效解决方法

给scroll-view 设置固定高度 【必须】 给scroll-view 样式添加 white-space: nowrap;属性【必须】 在scroll-view下的子模块设置 display: inline-block; 属性或 display: inline-table【必须】 在scroll-view下的子模块设置不得设置 float: left; 在scroll-view 上设置属性 sc…

混合APP的5种开发工具

近几年html5技术在各大平台都是人们谈论的焦点。html5技术一直受到各方关注,“html5颠覆原生 App”的争论也从未停止过,不管怎样html5生态的构建方兴未艾。不过对于移动开发者来说更关心的问题是如何低成本、周期短开发出体验效果好的App,所以…