意图:

  动态地给一个对象添加一些额外的职责,就增加功能而言,Decorator模式相比生成子类模式更为灵活

动机:

  有时我们希望给某个对象而不是整个类添加一些功能。例如,一个图形用户界面工具箱允许你对任意一个用户界面组件添加一些特性,例如边框,或是一些行为,例如窗口滚动。一种较为灵活的方式是将组件嵌入另一个对象中,由这个对象添加边框。我们称这个嵌入的对象为装饰 。这个装饰与它所装饰的组件接口一致,因此它对使用该组件的客户透明。

        例如,假定有一个对象 Te x t Vi e w,它可以在窗口中显示正文。缺省的 Te x t Vi e w没有滚动
条,因为我们可能有时并不需要滚动条。当需要滚动条时,我们可以用 S c r o l l D e c o r a t o r添加滚
动条。如果我们还想在 Te x t Vi e w周围添加一个粗黑边框,可以使用 B o r d e r D e c o r a t o r添加。因
此只要简单地将这些装饰和 Te x t Vi e w进行组合,就可以达到预期的效果。

结构:

例子:

以往画布上画一个圆为例来说明装饰模式的使用

 package designpatterns.strucural;
//抽象构件角色--Component
interface Shape {
void draw();
}
//具体构件角色--Concrete Component
class Circle implements Shape { @Override
public void draw() {
System.out.println("Shape: Circle");
}
} //装饰角色--Decorator
abstract class ShapeDecorator implements Shape{
protected Shape decoratedShape; public ShapeDecorator(Shape decoratedShape) {
this.decoratedShape = decoratedShape;
} public void draw() {
decoratedShape.draw();
}
} //具体装饰角色--Concrete Decorator1
class RedShapeDecorator extends ShapeDecorator { public RedShapeDecorator(Shape decoratedShape) {
super(decoratedShape);
} @Override
public void draw() {
decoratedShape.draw();
setRedBorder(decoratedShape);
} private void setRedBorder(Shape decoratedShape) {
System.out.println("Border Color: Red");
} } //具体装饰角色--Concrete Decorator2
class DottedLineShapeDecorator extends ShapeDecorator { public DottedLineShapeDecorator(Shape decoratedShape) {
super(decoratedShape);
} @Override
public void draw() {
decoratedShape.draw();
setLineType(decoratedShape);
} private void setLineType(Shape decoratedShape) {
System.out.println("Line type: dotted");
} } //画布
class Canvas{
void addshape(Shape shape){
shape.draw();
}
} //客户端
public class Decorator { public static void main(String[] args) { Canvas canvas = new Canvas();
Circle circle = new Circle(); canvas.addshape(circle);
System.out.println(); canvas.addshape(new RedShapeDecorator(circle));
System.out.println(); canvas.addshape(new DottedLineShapeDecorator(new RedShapeDecorator(circle)));
System.out.println();
} }

验证输出:

Shape: Circle

Shape: Circle
Border Color: Red Shape: Circle
Border Color: Red
Line type: dotted

代码说明:

最终使用该组件的客户为Canvas,由于装饰和它装饰的组件接口一致,客户就可以随意组合调用

1、绘制圆

2、绘制红色的圆

3、用虚线绘制红色的圆

你还可以添加更多的装饰,使用时只需要将这些装饰和组件Circul进行组合,就可以达到想要的效果

参考:

设计模式:桥接模式(Bridge)

Java与模式

设计模式:可复用面向对象软件的基础

装饰模式(decorator)的更多相关文章

  1. 装饰模式/decorator模式/结构型模式

    装饰模式Decorator 定义 为对象动态的增加新的功能,实现要求装饰对象和被装饰对象实现同一接口或抽象类,装饰对象持有被装饰对象的实例. java实现要点 定义一个接口或抽象类,作为被装饰者的抽象 ...

  2. 二十四种设计模式:装饰模式(Decorator Pattern)

    装饰模式(Decorator Pattern) 介绍动态地给一个对象添加一些额外的职责.就扩展功能而言,它比生成子类方式更为灵活.示例有一个Message实体类,某个对象对它的操作有Insert()和 ...

  3. 乐在其中设计模式(C#) - 装饰模式(Decorator Pattern)

    原文:乐在其中设计模式(C#) - 装饰模式(Decorator Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 装饰模式(Decorator Pattern) 作者:weba ...

  4. 设计模式 装饰模式(Decorator)

    设计模式 装饰模式(Decorator) @author ixenos 装饰模式是什么 1.装饰模式以对客户端透明的方式对象的功能,是继承关系的一个替代方案,但装饰模式可以在不创造更多子类的情况下,对 ...

  5. 设计模式-装饰模式(Decorator Pattern)

    装饰模式(Decorator Pattern):动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活

  6. Netty学习-IO体系架构系统回顾 & 装饰模式Decorator的具体使用

    Netty学习-IO体系架构系统回顾 IO和NIO的学习 NIO - 1.4 开始出的 在网络应用框架中,NIO得到了大量的使用,特别是netty里面 前提:对IO及其了解 对IO的总结和回顾 理解J ...

  7. 设计模式-09装饰模式(Decorator Pattern)

    1.模式动机 一般有两种方式可以实现给一个类或对象增加行为: 继承机制:使用继承机制是给现有类添加功能的一种有效途径,通过继承一个现有类可以使得子类在拥有自身方法的同时还拥有父类的方法.但是这种方法是 ...

  8. 设计模式系列之装饰模式(Decorator Pattern)——扩展系统功能

    说明:设计模式系列文章是读刘伟所著<设计模式的艺术之道(软件开发人员内功修炼之道)>一书的阅读笔记.个人感觉这本书讲的不错,有兴趣推荐读一读.详细内容也可以看看此书作者的博客https:/ ...

  9. 装饰模式 - Decorator 和 外观模式 - Facade

    装饰模式 Decorator,不改变接口但动态给对象加入责任,所需功能按顺序串联起来控制,比生成子类灵活. 外观模式 Facade,让接口更简单.为子系统中的一组接口提供一个一致的界面. 参考:

  10. [工作中的设计模式]装饰模式decorator

    一.模式解析 装饰模式又名包装(Wrapper)模式.装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案. 装饰模式的要点主要是: 1.需要对已有对象扩展新的功能,又不希望改变原有对 ...

随机推荐

  1. 实现一个栈类,类似STL中的栈

    1.思路讲解 stack集合类是一个简单的堆栈的实现. 这里有两个模板参数,T和size,T用于指定堆栈中的元素类型,my_size用于表示堆栈中项数的最大值. 类中添加方法isempty.isful ...

  2. pc端的企业网站(IT修真院test8)详解1-2

    今天接着说test8的页面还原. 头部header和尾部footer 我一开始是想直接使用bootstrap的栅格系统来实现的.但是内容的定位出了不少麻烦. 那么就索性用原生html+css来还原页面 ...

  3. Java并发编程(2):线程中断(含代码)

    使用interrupt()中断线程 当一个线程运行时,另一个线程可以调用对应的Thread对象的interrupt()方法来中断它,该方法只是在目标线程中设置一个标志,表示它已经被中断,并立即返回.这 ...

  4. 【tyvj1463】智商问题 [分块][二分查找]

    Background 各种数据结构帝~各种小姊妹帝~各种一遍AC帝~ 来吧! Description 某个同学又有很多小姊妹了他喜欢聪明的小姊妹 所以经常用神奇的函数来估算小姊妹的智商他得出了自己所有 ...

  5. cocos2dx之WebView踩过的坑(android返回键处理问题)

    最近游戏接入了一个私服平台,由于没有sdk,所以支付相关的操作需要在网页端进行,也就是说点击充值需要在游戏内部弹出一个网页,并定位到平台充值的地址.查阅相关资料后决定使用cocos2dx自带的WebV ...

  6. Unity编辑器重写Inspector面板,面板中编辑的数据不触发场景发生变化的问题。

    今天开始协助主程一起制作新框架.主程让我写关于新版UI框架注册UI预制体用的快捷编辑器. 现学现写,总算完成了. 可以直接把选中的预制体添加到UIController的数组中,期间涉及到改变大小.所以 ...

  7. Android高效内存之让你的图片省内存

    Android高效内存之让你的图片省内存 在做内存优化的时候,我们发现除了解决内存泄露问题,剩下的就只有想办法减少真实的内存占用.而在App中,大部分内存可能被我们图片占用了,所以减少图片的内存占用可 ...

  8. Angular4.0从入门到实战打造在线竞拍网站学习笔记之四--数据绑定&管道

    Angular4.0基础知识之组件 Angular4.0基础知识之路由 Angular4.0依赖注入 数据绑定 数据绑定允许你将组件控制器的属性和方法与组件的模板连接起来,大大降低了开发时的编码量. ...

  9. jQuery源码分析-03扩展工具函数jQuery.extend

    // 扩展工具函数 jQuery.extend({ // http://www.w3school.com.cn/jquery/core_noconflict.asp // 释放$的 jQuery 控制 ...

  10. Hadoop新生报到(一) hadoop2.6.0伪分布式配置详解

    首先先不看理论,搭建起环境之后再看: 搭建伪分布式是为了模拟环境,调试方便. 电脑是win10,用的虚拟机VMware Workstation 12 Pro,跑的Linux系统是centos6.5 , ...