装饰模式的定义:

  动态地将责任附加到对象向,若要扩展功能,装饰模式提供了比继承更有弹性的替代方案。

  遵循的设计原则是开闭原则,也是对扩展开放,对修改关闭。

下面是类图

示例代码

/**
*定义被装饰者
*
*/
public interface Human { public void wearClothers(); public void walkToWhere();
} /**
* 定义抽象装饰者
*
*/
public abstract class Decorate implements Human { Human human; public Decorate(Human human) {
this.human = human;
} public void wearClothers() {
this.human.wearClothers();
} public void walkToWhere() {
this.human.walkToWhere();
}
} /**
*
*装饰者 zero
*/
public class DecorateZero extends Decorate{ public DecorateZero(Human human) {
super(human);
} @Override
public void walkToWhere() {
super.walkToWhere();
System.out.println("Zero.............walkToWhere");
} @Override
public void wearClothers() {
super.wearClothers();
System.out.println("Zero.............wearClothers");
}
} /**
* 装饰者two
*
*/
public class DecorateTwo extends Decorate{ public DecorateTwo(Human human) {
super(human);
}
@Override
public void walkToWhere() {
super.walkToWhere();
System.out.println("Two.............walkToWhere");
} @Override
public void wearClothers() {
super.wearClothers();
System.out.println("Two.............wearClothers");
}
} //
public class DecorateFirst extends Decorate{ public DecorateFirst(Human human) {
super(human);
} @Override
public void walkToWhere() {
super.walkToWhere();
System.out.println("First.............walkToWhere");
} @Override
public void wearClothers() {
super.wearClothers();
System.out.println("First.............wearClothers");
}
} /**
*
*测试代码
*/
public class Test { public static void main(String[] args) {
DecorateZero zero=new DecorateZero(new DecorateFirst(new DecorateTwo(new Human() {
//这里装饰者原有的行为,这里我没有具体去写实现类。
@Override
public void wearClothers() {
// TODO Auto-generated method stub
System.out.println("1111111wearClothers1111111"); } @Override
public void walkToWhere() {
// TODO Auto-generated method stub
System.out.println("1111111walkToWhere1111111");
}
})));
zero.walkToWhere();
System.out.println("*******************************************");
zero.wearClothers();
}
} //测试结果
1111111walkToWhere1111111
Two.............walkToWhere
First.............walkToWhere
Zero.............walkToWhere
*******************************************
1111111wearClothers1111111
Two.............wearClothers
First.............wearClothers
Zero.............wearClothers

关键点:
1、Decorator抽象类中,持有Human接口,方法全部委托给该接口调用,目的是交给该接口的实现类即子类进行调用。
2、Decorator抽象类的子类(具体装饰者),里面都有一个构造方法调用super(human),这一句就体现了抽象类依赖于子类实现即抽象依赖于实现的原则。因为构造里面参数都是Human接口,只要是该Human的实现类都可以传递进去,即表现出Decorator dt = new Decorator_second(new Decorator_first(new
Decorator_zero(human)));这种结构的样子。所以当调用dt.wearClothes();dt.walkToWhere()的时候,又因为每个具体装饰者类中,都先调用super.wearClothes和super.walkToWhere()方法,而该super已经由构造传递并指向了具体的某一个装饰者类(这个可以根据需要调换顺序),那么调用的即为装饰类的方法,然后才调用自身的装饰方法,即表现出一种装饰、链式的类似于过滤的行为。
3、具体被装饰者类,可以定义初始的状态或者初始的自己的装饰,后面的装饰行为都在此基础上一步一步进行点缀、装饰。
4、装饰者模式的设计原则为:对扩展开放、对修改关闭,这句话体现在我如果想扩展被装饰者类的行为,无须修改装饰者抽象类,只需继承装饰者抽象类,实现额外的一些装饰或者叫行为即可对被装饰者进行包装。

装饰Java.io类

java.io包内的类太多了,简只是……”排山倒海“,其实是因为里面许多类都是装饰者,其实java.io也引出装饰者模式的一个缺点:利用装饰着模式,常常设计中有大量的小类,数量实在太多,造成使用者非常大的困扰。了解装饰者模式的原理看起就会简单多了。

编写自己的java.io装饰者

功能:把输入的大写字母写成小写
例如:This is LONGHAIBO,使用此装饰者变成this is longhaibo

public class TestDecorate {

    public static void main(String[] args) {

        int c;
try (InputStream in = new LowerCaseIputStream(new BufferedInputStream(
new FileInputStream("src/decorate.txt")))) {
while ((c=in.read())>0) {
System.out.print((char)c);
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
} }
} /**
* Java io 装饰者模式
* 功能:把输入的大写字母写成小写
* 例如:This is LONGHAIBO,使用此装饰者变成this is longhaibo
*
*/
class LowerCaseIputStream extends FilterInputStream { protected LowerCaseIputStream(InputStream in) {
super(in);
}
//针对字节
@Override
public int read() throws IOException {
int c=super.read();
return (c==-1?c:Character.toLowerCase((char)c));
}
//针对字节数组
@Override
public int read(byte[] b, int off, int len) throws IOException {
int result=super.read(b, off, len);
for (int i = off; i < off+result; i++) {
b[i]=(byte)Character.toLowerCase((char)b[i]);
}
return result;
} }

输出结果

this is longhaibo

参考资料

head_first设计模式(中文版)

http://blog.csdn.net/jason0539/article/details/22713711

  

Decorate Pattern 装饰者模式的更多相关文章

  1. Decorator Pattern (装饰者模式)

    装饰者模式( Decorator Pattern ) 意图 : 动态的给一个对象添加一些额外的功能,IO这块内容体现出了装饰模式,Decorator模式相比生成子类更为灵活. 角色 : 1)抽象构件角 ...

  2. 浅谈设计模式--装饰者模式(Decorator Pattern)

    挖了设计模式这个坑,得继续填上.继续设计模式之路.这次讨论的模式,是 装饰者模式(Decorator Pattern) 装饰者模式,有时也叫包装者(Wrapper),主要用于静态或动态地为一个特定的对 ...

  3. java之装饰器模式

    Decorator Pattern(装饰器模式),定义:Attach additional responsibilities to an object dynamically. Decorators  ...

  4. 设计模式(三):“花瓶+鲜花”中的装饰者模式(Decorator Pattern)

    在前两篇博客中详细的介绍了"策略模式"和“观察者模式”,今天我们就通过花瓶与鲜花的例子来类比一下“装饰模式”(Decorator Pattern).在“装饰模式”中很好的提现了开放 ...

  5. C#设计模式之装饰者模式(Decorator Pattern)

    1.概述 装饰者模式,英文名叫做Decorator Pattern.装饰模式是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能.它是通过创建一个包装对象,也就是装饰来包裹真实的对象. 2 ...

  6. java_设计模式_装饰者模式_Decorator Pattern(2016-07-28)

    装饰模式又名包装(Wrapper)模式.装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案. 装饰模式的结构 装饰模式以对客户透明的方式动态地给一个对象附加上更多的责任.换言之,客户 ...

  7. 设计模式 - 装饰者模式(Decorator Pattern) Java的IO类 用法

    装饰者模式(Decorator Pattern) Java的IO类 用法 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26716 ...

  8. 设计模式 - 装饰者模式(Decorator Pattern) 具体解释

    装饰者模式(Decorator Pattern) 具体解释 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26707033 装饰者 ...

  9. 设计模式学习--装饰者模式(Decorator Pattern)

    概念: 装饰者模式(Decorator Pattern): 动态地将功能添加到对象,相比生成子类更灵活,更富有弹性. 解决方案: 装饰者模式的重点是对象的类型,装饰者对象必须有着相同的接口,也也就是有 ...

随机推荐

  1. JavaACOFramework的各个类介绍(part2 : Ant4AS类)

    package aco.ant; import java.util.ArrayList; import util.RouletteWheel;//引入轮盘类 import aco.ACO;//引入蚁群 ...

  2. background-position (转)

    http://blog.csdn.net/JeamKing/article/details/5617088   注:这是别人博客链接地址  具体效果图片可以查看此链接 语法:background-po ...

  3. Canvas实现图片放大缩小移动操作

    对于HTML5相信大家都不陌生,很早就出来了,但是貌似都没有真正的使用过.最近做项目时要实现这样一个需求:一个图片,大小不固定,要求能实现类似地图一样放大.缩小.移动功能.这里就很合适使用html5的 ...

  4. idea打包java可执行jar包

    1,在项目上鼠标右键 --> Open Module Settings 2, Artifacts --> + --> JAR --> From modules with dep ...

  5. css清除浮动float的三种方法总结,为什么清浮动?浮动会有那些影响?一起来$('.float')

    一.抛一块问题砖(display: block)先看现象: 分析HTML代码结构: <div class="outer">     <div class=&quo ...

  6. laravel select 传参

    传值: $params['select'] = 'taobao_id,title,image,price,coupon_deduct,coupon_condition'; 接受参数 $result = ...

  7. PHP绘图

    创建图像的一般流程1.设定标头,告诉浏览器你要生成的绘图类型.2.创建一个图像区域,以后的操作都将基于此图像区域.3.在空白图像区域绘制填充背景.4.在背景上绘制图形轮廓输入文本.5.输出最终图形.6 ...

  8. iOS开发 iOS10兼容访问http

    添加NSAppTransportSecurity的字典会自动变成  AppTransportSecurity再添加 allow Arbitary Loads  Boolean   YES

  9. ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)

    在安装好的MySQL服务器上,配置了环境变量之后,发现用mysql无法登录,报如题的错误,实在没有办法,决定用安全模式对root用户修改密码: 首先关闭正在运行的MySQL; 在一个终端窗口运行命令: ...

  10. Oracle 表连接

    Oracle 表之间的连接分为三种: 1. 内连接(自然连接) 2. 外连接 (1)左外连接 (左边的表不加限制)      (2)右外连接(右边的表不加限制)      (3)全外连接(左右两表都不 ...