意图:

  动态地给一个对象添加一些额外的职责,就增加功能而言,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. [权限相关]在PeopleSoft中查找可以使用DataMover的用户

    DataMover是一个功能非常强大的工具,它的访问权限应该被控制,特别是在PRD环境中.在每个公司,许多用户可能在一段时间内切换部门,角色和职责,所以每隔一段时间就应该检查这些用户的权限,以确认他们 ...

  2. eclipse maven构建

    run as --> maven install 1.No compiler is provided in this environment. Perhaps you are running o ...

  3. IDEA 单元测试testng入门及testng.xml

    直接进入正题: 1.TestNG的运行方式如下: With a testng.xml file 直接run as test suite With ant 使用ant From the command ...

  4. BZOJ-1491-社交网络

    题目链接:https://vjudge.net/problem/HYSBZ-1491 题目大意:中文题目,题意见题目 题目分析:由于数据量很小,可以考虑进行Floyd算法. 第一次进行Floyd算法, ...

  5. JavaSE的基础语法之标识符:

    标识符(掌握) (1)就是给类,接口,方法,变量等起名字的字符序列 (2)组成规则: A:英文大小写字母 B:数字 C:$和_ (3)注意事项: A:不能以数字开头 B:不能是java中的关键字 C: ...

  6. Python-cookies

    附新手工具: python新手工具下载链接:http://pan.baidu.com/s/1eS8WMR4 密码:7eso 注册码:http://idea.liyang.io py和编辑器安装教程链接 ...

  7. 说一说Jquery中的empty()与remove()的区别和用法

    今天在改一个新人写的代码,好吧,我承认改代码比自己写代码要来的痛苦. 主要是在测试一个table.table中有一列是删除操作.我的删除功能是 这样的,当点击删除的时候,判断这个table中的tr行是 ...

  8. [Android]Android焦点流程代码分析

    以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/7286503.html 通过View的View::focusSe ...

  9. 配置SSH隧道访问Ubuntu服务器上的MongoDB

    为了数据安全,在MongoDB的配置文件里,一般会把默认的27017端口port改为自定义的端口号,然后把允许访问的IP设为127.0.0.1(即主机本身).但是这样就会在开发的过程查看数据时带来麻烦 ...

  10. ABP+AdminLTE+Bootstrap Table权限管理系统第一节--使用ASP.NET Boilerplate模板创建解决方案

    "abp是ASP.NET Boilerplate简称,是一个用最佳实践和流行技术开发现代WEB应用程序的新起点,它旨在成为一个通用的WEB应用程序框架和项目模板" abp官方网站: ...