5.装饰模式 Decorator (单一职责)
2.动机
- 在某些情况下我们可能会“过度地使用继承来扩展对象的功能”,由于继承为类型引入的静态特质,使得这种扩展方式缺乏灵活性;并且随着子类的增多(扩展功能的增多),各种子类的组合(扩展功能的组合)会导致更多子类的膨胀。
- 如何使“对象功能的扩展”能够根据需要来动态地实现?同时避免“扩展功能的增多”带来的子类膨胀问题?从而使得任何“功能扩展变化”所导致的影响降为最低?
3.要点总结
- 通过采用组合而非继承的手法,Decorator模式实现了在运行时动态扩展对象功能的能力,而且可以根据需要扩展多个功能。避免了使用继承带来的“灵活性差”和“多子类衍生问题”。
- Decorator类在接口上表现为is-a Component的继承关系(继承+组合),即Decorator类继承了Component类所具有的接口。但在实现上又表现为has-a Component的组合关系,即Decorator类又使用了另外一个Component类。
- Decorator模式的目的并非解决“多子类衍生的多继承”问题,Decorator模式应用的要点在于解决“主体类在多个方向上扩展功能”--是为“装饰”的含义。
4.uml类图

5.实现
5.1抽象枪械
public abstract class Gun {
public abstract void load();//装子弹
public abstract void fire();//发射子弹
}
5.2具体枪械
public class Gun98K extends Gun {
@Override
public void load() {
Log.e("Gun98K", "装满5发子弹");
}
@Override
public void fire() {
Log.e("Gun98K", "开始点射");
}
}
public class GunM416 extends Gun {
@Override
public void load() {
Log.e("GunM416", "装子弹");
}
@Override
public void fire() {
Log.e("GunM416", "开始扫射");
}
}
5.3抽象装饰器
public abstract class GunDecorator extends Gun {
Gun gun;
public GunDecorator(Gun gun) {
this.gun = gun;
}
@Override
public void load() {
gun.load();
}
@Override
public void fire() {
gun.fire();
}
}
5.4具体装饰器
/**
* Describe: 加枪托
*/
public class ButtGunDecorator extends GunDecorator {
String butt;
public ButtGunDecorator(Gun gun, String butt) {
super(gun);
this.butt = butt;
}
@Override
public void load() {
gun.load();
}
@Override
public void fire() {
Log.e("ButtGun", "降低垂直水平后坐力");
gun.fire();
}
}
/**
* Created by nbb on 2020/12/26
* Version 1.0
* Describe:子弹袋装饰
*/
public class BulletBagGunDecorator extends GunDecorator {
String sight;
public BulletBagGunDecorator(Gun gun, String sight) {
super(gun);
this.sight = sight;
}
@Override
public void load() {
Log.e("BulletBagGunDecorator", sight + "快速");
gun.load();
}
@Override
public void fire() {
gun.fire();
}
}
/**
* Created by nbb on 2020/12/26
* Version 1.0
* Describe:瞄具
*/
public class SightGunDecorator extends GunDecorator {
String sight;
public SightGunDecorator(Gun gun, String sight) {
super(gun);
this.sight = sight;
}
@Override
public void load() {
gun.load();
}
@Override
public void fire() {
Log.e("SightGun", sight + "打开 放大目标");
gun.fire();
}
}
5.5测试
Gun m416 = new GunM416();//捡到一把M4
Gun sightM416 = new SightGunDecorator(m416, "4倍镜");//捡到一个4倍镜
Gun buttSightM416 = new ButtGunDecorator(sightM416, "M416枪托");//捡到一个枪托
buttSightM416.load();
buttSightM416.fire();
//捡到一把满配98K
Gun gun98k = new SightGunDecorator(new BulletBagGunDecorator(new Gun98K(),
"98k子弹袋"),"8倍镜");
gun98k.load();
gun98k.fire();
//结果
// GunM416: 装子弹
// ButtGun: 降低垂直水平后坐力
// SightGun: 4倍镜打开 放大目标
// GunM416: 开始扫射
// BulletBagGunDecorator: 98k子弹袋快速
// Gun98K: 装满5发子弹
// SightGun: 8倍镜打开 放大目标
// Gun98K: 开始点射

5.装饰模式 Decorator (单一职责)的更多相关文章
- 设计模式---单一职责模式之装饰模式(Decorator)
前提:"单一职责"模式 在软件组件的设计中,如果责任划分的不清晰,使用继承,得到的结果往往是随着需求的变化,子类急剧膨胀,同时充斥着重复代码,这时候的关键是划清责任 典型模式(表现 ...
- C++设计模式 之 “单一职责”模式:Decorator、Bridge
part 1 “单一职责”模式 在软件组件的设计中,如果责任划分的不清晰,使用继承得到的结果往往是随着需求的变化,子类急剧膨胀,同时充斥着重复代码,这时候的关键是划清责任. 典型模式 Decorato ...
- 23种设计模式 - 单一职责(Decorator - Bridge)
其他设计模式 23种设计模式(C++) 每一种都有对应理解的相关代码示例 → Git原码 ⌨ 单一职责 在软件组件的设计中,如果责任划分的不清晰,使用继承得到的结果往往是随着需求的变化,子类急剧膨胀, ...
- 设计模式---单一职责模式之桥模式(Bridge)
一:概念 Bridge模式又叫做桥接模式,其实基于类的最小设计原则,通过使用封装,聚合以及继承等行为来让不同的类承担不同的责任他的主要特点是吧抽象与行为实现分离开来,从而可以保持各部分的独立性以及一对 ...
- 学习记录:《C++设计模式——李建忠主讲》4.“单一职责”模式
单一职责模式:在软件组件的设计中,如果责任划分的不清晰,使用继承得到的结果往往是随着需求的变化,子类急剧膨胀,同时充斥着重复代码,这时候的关键是划清责任. 典型模式:装饰模式(Decorator).桥 ...
- 二十四种设计模式:装饰模式(Decorator Pattern)
装饰模式(Decorator Pattern) 介绍动态地给一个对象添加一些额外的职责.就扩展功能而言,它比生成子类方式更为灵活.示例有一个Message实体类,某个对象对它的操作有Insert()和 ...
- 乐在其中设计模式(C#) - 装饰模式(Decorator Pattern)
原文:乐在其中设计模式(C#) - 装饰模式(Decorator Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 装饰模式(Decorator Pattern) 作者:weba ...
- 设计模式 装饰模式(Decorator)
设计模式 装饰模式(Decorator) @author ixenos 装饰模式是什么 1.装饰模式以对客户端透明的方式对象的功能,是继承关系的一个替代方案,但装饰模式可以在不创造更多子类的情况下,对 ...
- 设计模式-装饰模式(Decorator Pattern)
装饰模式(Decorator Pattern):动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活
- 设计模式-09装饰模式(Decorator Pattern)
1.模式动机 一般有两种方式可以实现给一个类或对象增加行为: 继承机制:使用继承机制是给现有类添加功能的一种有效途径,通过继承一个现有类可以使得子类在拥有自身方法的同时还拥有父类的方法.但是这种方法是 ...
随机推荐
- PyQt(Python+Qt)学习随笔:QMainWindow的addDockWidget方法增加QDockWidget停靠窗到主窗口
专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt入门学习 老猿Python博文目录 DockWidget除了放在QMainWindow窗口内外,也可以放在 ...
- Model/View开发小结
老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 Model/View开发是PyQt和Qt中重要的框架之一,老猿认为另外两个就是信号槽机制和事件机制, ...
- PyQt(Python+Qt)学习随笔:使用pyqtConfigure建立信号和槽的连接
老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 在PyQt中,一般信号和槽的连接是通过connect方法建立的,语法如下: connect(slot ...
- PyQt学习随笔:Model/View中视图数据项编辑变动实时获取变动数据的方法
对于Model/View中视图的数据编辑后怎么能实时获取编辑的数据变动位置和变动情况查阅了一些资料,终于基本弄明白必须重写Model的setData方法才能截获.setData方法是视图中各种角色数据 ...
- PyQt(Python+Qt)学习随笔:gridLayout的layoutRowMinimumHeight和layoutColumnMinimumWidth属性
Qt Designer中网格布局(gridLayout)中,layoutRowMinimumHeight和layoutColumnMinimumWidth两个属性分别设置网格布局中各行的最小高度和各列 ...
- Kubernetes 教程:在 Containerd 容器中使用 GPU
原文链接:https://fuckcloudnative.io/posts/add-nvidia-gpu-support-to-k8s-with-containerd/ 前两天闹得沸沸扬扬的事件不知道 ...
- 补:冲刺Day2
每天举行站立式会议照片: 昨天已完成的工作: 各个成员在 Alpha 阶段认领的任务. 今天各个成员的任务安排. 冲刺Day1博客. 今天计划完成的工作: 成员 任务 高嘉淳 完成登陆.注册 覃泽泰 ...
- 题解-CTS2019 珍珠
题面 CTS2019 珍珠 有 \(n\) 个在 \([1,d]\) 内的整数,求使可以拿出 \(2m\) 个整数凑成 \(m\) 个相等的整数对的方案数. 数据范围:\(0\le m\le 10^9 ...
- 四、Zookeeper伪集群搭建
伪集群模式 Zookeeper不但可以在单机上运行单机模式 Zookeeper,而且可以在单机模拟集群模式 Zookeeper的运 行,也就是将不同实例运行在同一台机器,用端口进行区分,伪集群模式为我 ...
- Vue项目上线环境部署,项目优化策略,生成打包报告,及上线相关配置
Node.js简介 Node.js是一个基于Chrome V8引擎的JavaScript运行环境,用来方便快速地搭建易于扩展的网络应用.Node.js使用了一个事件驱动.非阻塞式I/O的模型,使其轻量 ...