需加装饰——装饰模式

装饰模式指的是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。

类图分析

我们先假设一个业务场景,有三种房子需要装修,分别是公寓,木屋和别墅,装修的方式有刷墙和摆满鲜花。那么应用装饰模式以后的类图结构如下所示:

image

这个结构似乎与组合模式非常像,然而内部却大有不同。截止到Decorate部分,左上部分完全与组合模式相同,Decorate类是装饰类的核心类。

代码展示

package pattern.decorate;/*** 装饰类基类,注意要继承构建类基类,同时关联一个基类对象* * @author Evsward**/
public class Decorate extends House {protected House house;public Decorate() {// 给出一个默认值,防止house空值异常。this.house = new Cabin();}public Decorate(House house) {this.house = house;}@Overridepublic void show() {house.show();}}

这里面关键点为:

  • Decorate类也继承了House抽象基类。
  • 同时它还包含一个House对象的成员属性。
  • 该属性在构造器中被初始化。
  • 其复写的抽象方法并未实现任何具体内容,而是直接调用House对象的show方法。

然后请看Decorate的子类的实现方式,他们是如何具体的扩展构建类的。

package pattern.decorate;public class GreenWallHouse extends Decorate {public GreenWallHouse(House h) {super(h);}private void painGreenOnWall() {logger.info("The wall is green now.");}@Overridepublic void show() {super.show();painGreenOnWall();}}

FlowerHouse也是同理。它们的关键点是:

  • 必须创建构造函数,将House对象传入。
  • 在实现抽象方法时,直接调用House对象的show方法,同时加入自己的“装饰”内容。

角色分析

装饰模式中重要的角色主要有两个,正是上面代码展示部分的那两个,他们可以总结为:

  1. Decorate类,它继承自构建基类,并不作任何具体动作,却是架构中重要的一环。
  2. ConcreteDecorate类,继承自Decorate类,作具体的扩展功能。

优势

装饰模式的架构平淡无奇,但是却可以不断套用,我们来看客户端的调用:

package pattern.decorate;import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.junit.Test;public class Client {public final static Logger logger = LogManager.getLogger();@Testpublic void testDecorate() {House a = new Apartment();a.show();logger.info("---------------");House aPlus = new GreenWallHouse(a);aPlus.show();logger.info("---------------");/*** 因为他们都继承了House,是同一个基类,所以可以无限套用装饰类去循环。*/House aPPlus = new GreenWallHouse(new FlowerHouse(a));aPPlus.show();}
}

输出:

14:38:45[show]: This is my apartment, which is on the high floor.
14:38:45[testDecorate]: ---------------
14:38:45[show]: This is my apartment, which is on the high floor.
14:38:45[painGreenOnWall]: The wall is green now.
14:38:45[testDecorate]: ---------------
14:38:45[show]: This is my apartment, which is on the high floor.
14:38:45[decorateFlowerAround]: The room is full of flowers now.
14:38:45[painGreenOnWall]: The wall is green now.

由于装饰模式中所有新增的类都是构建类的子类,并且他们每个类都声明了以构建类对象为参数的构造函数,因此,具体装饰类可以直接套用拓展,正如以上代码所示。

装饰模式,符合了面向对象设计原则“对修改关闭,对拓展开放”的原则。在原有代码完全不改动的情况下,可以有效拓展系统功能。并且通过不断的套用构造函数的方式,使得原始构建类得到了多层的功能拓展,这有效地代替了多继承。在JavaIO中,装饰模式得到了广泛使用。

转载于:https://www.cnblogs.com/Evsward/p/decorate.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/370420.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Vue2.0 --- vue-cli脚手架中全局引入JQ

第一步:安装jQuery npm/cmpn方式安装(默认安装1.7.X版本的JQ) npm/cnpm install jQuery 如果想安装更高版本的JQ那么可以选择在package.json文件下面这个位置添加代码断(当前图片安装的是2.2.3版本,如果想安装更高或者其他可以更改版本号&…

Unity——用UnityEditor拷贝FBX中的AnimationClip

最近有个新需求,要用代码添加动画的事件,但是Unity不能直接修改FBX中的AnimationClip 在Animation窗口中可以看到,AnimationClip是Read-Only状态,用代码修改这个AnimationClip也是不会生效的,包括用代码添加事件 解决方…

mvc如何嵌套第三方页面_长文观点丨为什么我不再使用MVC框架?

原创: 张卫滨 译 Jean-Jacques Dubray是一名资深工程师,他最近引入了一个新的模式:状态-行为-模(State-Action-Model,SAM)。SAM是一个函数式反应型的编程模式,它致力于简化数据Model和View之间的交互。它究竟有何优点值…

JSON和XML的区别

转载于:https://www.cnblogs.com/mr-wuxiansheng/p/6974239.html

屏幕适配

rem是什么? rem(font size of the root element)是指相对于根元素的字体大小的单位。简单的说它就是一个相对单位。看到rem大家一定会想起em单位,em(font size of the element)是指相对于父元素的字体大小…

【存储过程】MySQL存储过程/存储过程与自定义函数的区别

---------------------------存储过程-------------------- 语法: 创建存储过程: CREATE [definer {user|current_user}] PROCEDURE sp_name ([ proc_parameter [,proc_parameter ...]]) [ characteristics..] routime_body 其中: proc_parameter : [IN|OUT|INOUT] parameter_…

Java死锁故障排除和解决

JavaOne年度会议的一大优点是,主题专家介绍了几个技术和故障排除实验室。 其中的一个实验室今年特别吸引了我的注意力:“ HOL6500-查找和解决Java死锁 ”,由Java冠军Heinz Kabutz提出 。 这是我在该主题上看到的最好的演示之一。 我建议您自己…

3. HTML中的容器标签

什么是容器标签&#xff1f;在HTML开发中我们常常会使用一类标签作为容器放置一些内容&#xff0c;我们把这类标签称之为容器标签&#xff0c;可以作为容器标签的包括列表标签、表格标签、框架标签、布局标签&#xff0c;在这里我们就来总结下这些内容。 列表标签 1 <!-- 无…

GitHub上Java的Bloom Bloom实现

布隆过滤器是集数据结构的一种 。 对于那些不了解的对象&#xff0c;“设置数据结构”仅包含一个主要方法。 它仅用于确定特定元素是否包含在一组元素中。 大多数数据结构&#xff08;例如Hash Map &#xff0c; Linked List或Array &#xff09;都可以相当轻松地创建此函数。 …

ni软件管理器_NI 技术支持丨我的 NI 硬件设备不能被识别,怎么办?Windows

这篇指南可以帮助您解决在您的 Windows 系统上无法识别您的 NI 硬件有关的问题。症状包括以下几种情况&#xff1a;连接至 USB 端口时&#xff0c;硬件上的 LED 灯不亮/不闪烁。连接至 USB 后已连接设备的 LED 灯持续闪烁。仅限音频接口&#xff1a;该设备在音频应用程序或 Win…

在Java应用程序中使用密码学

这篇文章描述了如何使用Java密码体系结构 &#xff08;JCA&#xff09;&#xff0c;该体系结构使您可以在应用程序中使用密码服务。 Java密码体系结构服务 JCA提供了许多加密服务&#xff0c;例如消息摘要和签名 。 这些服务可以通过特定于服务的API来访问&#xff0c;例如Me…

CSS学习笔记-04 a标签-导航练习

个人练习&#xff0c;各位大神勿笑 。。 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><meta http-equiv&qu…

深度学习loss值变为0_利用TensorFlow2.0为胆固醇、血脂、血压数据构建时序深度学习模型(python源代码)...

背景数据描述胆固醇、高血脂、高血压是压在广大中年男性头上的三座大山&#xff0c;如何有效的监控他们&#xff0c;做到早发现、早预防、早治疗尤为关键&#xff0c;趁着这个假期我就利用TF2.0构建了一套时序预测模型&#xff0c;一来是可以帮我预发疾病&#xff0c;二来也可以…

在Spring MVC Web应用程序中使用reCaptcha

CAPTCHA是一种程序&#xff0c;可以生成人类可以通过的测试并对其进行评分&#xff0c;而计算机程序“ 不能 ”通过。 所采取的策略之一是向用户显示具有扭曲文本的图像&#xff0c;并且用户应在输入区域中书写文本。 如果显示的文字与用户输入的文字相同&#xff0c;则我们可以…

课时109.外边距合并现象(掌握)

我们先写一个案例&#xff0c;通过案例来了解 它们之间的水平距离就是两个间距的和 我们看完水平再来看垂直方向 在默认布局的垂直方向上&#xff0c;默认情况下外边距是不会叠加的&#xff0c;会出现合并现象&#xff0c;谁的外边距比较大就听谁的 本文转载于:猿2048➜https:…

纯 CSS实现三角形

最近项目上做评论回复&#xff0c;设计师提高交互性特意设计了小三角&#xff0c;如下&#xff1a; 下面介绍一下实现效果的css方法&#xff1a; 1.border 通过设置上下左右border宽度来实现。 首先查看一下全部设置的效果&#xff1a; <style>   .triangle{     w…

Spring MVC表单验证(带批注)

这篇文章提供了一个简单HTML表单验证示例。 它基于带有注释的Spring MVC示例。 该代码可在GitHub的Spring-MVC-Form-Validation目录中找到。 数据 在此示例中&#xff0c;我们将使用bean和JSR303验证批注&#xff1a; public class MyUser {NotNullSize(min1,max20)private …

课时106.边框练习(理解)

让我们做出来如下的样式&#xff1a; 1.首先看下有几个边框&#xff0c;就做几个div&#xff0c;用简单方法div.box$*6 tab键 2.然后给它们设置宽高 3.然后依此来做边框 第一个&#xff1a;有四种方法&#xff0c;第一种最简单 第二个&#xff1a;有两种方法&#xff0c;第二…

课时105.边框属性下(掌握)

2.3连写&#xff08;分别设置四条边的边框&#xff09; border-width:上 右 下 左; border-style:上 右 下 左; border-color:上 右 下 左; 注意点&#xff1a; 1.这三个属性的取值是按顺时针来赋值的 也就是按照上右下左来赋值&#xff0c;而不是按照日常生活…

新mac 下第一次 安装 mongodb 步骤

新入手mac&#xff0c;安装mongo步骤记录&#xff1a;不建议使用网上的brew安装方法&#xff0c;因为试了半天没有成功&#xff0c;应该是新版本限制比较多&#xff01; 从mongodb官网下载mac版本mongo&#xff1a; 1.访问MongoDB官方下载地址 http://www.mongodb.org/download…