设计模式学习笔记之装饰者模式

装饰者模式

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

说明:

1、装饰者和被装饰者对象有相同的超类型;

2、可以用一个或者多个装饰者包装一个对象;

3、既然装饰者和被装饰者对象有相同的超类型,所以在任何需要原始对象(被装饰者)的场合,可以用装饰过的对象代替它;

4、装饰者可以在委托被装饰者的行为之前 与 / 或 之后,加上自己的行为,以达到特定的目的

5、对象可以在任何时候被装饰,所以可以在运行时动态地、不限量地用你喜欢的装饰者来装饰对象。

在装饰模式中的角色有:

抽象构件(Component)角色:给出一个抽象接口,以规范准备接收附加责任的对象。

具体构件(ConcreteComponent)角色:定义一个将要接收附加责任的类。

装饰(Decorator)角色:持有一个构件(Component)对象的实例,并定义一个与抽象构件接口一致的接口。

具体装饰(ConcreteDecorator)角色:负责给构件对象“贴上”附加的责任。

/**

* 孙悟空的本尊,并且定义了七十二变的方法。

* 抽象构件(Component)角色

*/

public abstract class Monkey {

protected String type = "本尊";

protected abstract void change();

public String getType() {

return type;

}

}

/**

* 齐天大圣

* 具体构件(ConcreteComponent)角色

* */

public class MonkeyKing extends Monkey{

public MonkeyKing() {

type = "齐天大圣 -> ";

}

@Override

protected void change() {

System.out.println("七十二变......");

}

}

/**

* 变化的孙悟空

* 装饰(Decorator)角色

* */

public abstract class ChangeMonkey extends Monkey{

@Override

protected abstract void change();

}

/**

* 变化后为鱼

* 具体装饰(ConcreteDecorator)角色

* */

public class Fish extends ChangeMonkey{

private Monkey monkey;

public Fish(Monkey monkey) {

this.monkey = monkey;

}

@Override

protected void change() {

System.out.println("变化为 Fish ......");

}

public String getType() {

return monkey.getType() + "fish -> ";

}

}

/**

* 变化后为鸟

* 具体装饰(ConcreteDecorator)角色

* */

public class Bird extends ChangeMonkey{

private Monkey monkey;

public Bird(Monkey monkey) {

this.monkey = monkey;

}

@Override

protected void change() {

System.out.println("Bird......");

}

public String getType() {

return monkey.getType() + "bird -> ";

}

}


public class Client {

public static void main(String[] args) {

Monkey monkey = new MonkeyKing();

Monkey fish = new Fish(monkey);

Monkey fish2 = new Fish(fish);

Monkey bird = new Bird(fish2);

System.out.println(bird.getType());

bird.change();

}

}

    装饰着模式在 Java I/O 中的应用

根据上图可以看出:

  ●  抽象构件(Component)角色:由InputStream扮演。这是一个抽象类,为各种子类型提供统一的接口。

  ●  具体构件(ConcreteComponent)角色:由ByteArrayInputStream、FileInputStream、PipedInputStream、StringBufferInputStream等类扮演。它们实现了抽象构件角色所规定的接口。

  ●  抽象装饰(Decorator)角色:由FilterInputStream扮演。它实现了InputStream所规定的接口。

  ●  具体装饰(ConcreteDecorator)角色:由几个类扮演,分别是BufferedInputStream、DataInputStream以及两个不常用到的类LineNumberInputStream、PushbackInputStream。

装饰模式的优点

  (1)装饰模式与继承关系的目的都是要扩展对象的功能,但是装饰模式可以提供比继承更多的灵活性。装饰模式允许系统动态决定“贴上”一个需要的“装饰”,或者除掉一个不需要的“装饰”。继承关系则不同,继承关系是静态的,它在系统运行前就决定了。

  (2)通过使用不同的具体装饰类以及这些装饰类的排列组合,设计师可以创造出很多不同行为的组合。

装饰模式的缺点

  由于使用装饰模式,可以比使用继承关系需要较少数目的类。使用较少的类,当然使设计比较易于进行。但是,在另一方面,使用装饰模式会产生比使用继承关系更多的对象。更多的对象会使得查错变得困难,特别是这些对象看上去都很相像。

参考资料:《Head First 设计模式》

http://www.cnblogs.com/java-my-life/archive/2012/04/20/2455726.html

时间: 2024-08-03 09:08:59

设计模式学习笔记之装饰者模式的相关文章

《Head First 设计模式》学习笔记——观察者模式 + 装饰者模式

装饰者模式是JDK中另一个使用较多的设计模式,上一个是观察者模式(在Swing中大量使用),业内好的API设计无一离不开常见的设计模式,通常我们所说要阅读源码,也是为了学习大牛们的设计思路.----题记 设计模式 观察者模式:定义了对象之间一对多的依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会受到通知并自动更新. 装饰者模式:动态地将责任附加到对象上.若要扩展功能,装饰者提供比继承者更有弹性的替代方案. 设计原则 (1)封装变化. (2)多用组合,少用继承. (3)针对接口编程,而不是

PHP设计模式学习笔记: 责任链模式(Chain of Responsibility)

// 抽象书本类 abstract class AbstractBookTopic { abstract function getTopic(); abstract function getTitle(); abstract function setTitle($title_in); } // 书本类,继承自抽象书本类 class BookTopic extends AbstractBookTopic { private $topic; private $title; function __co

设计模式学习总结(七)--装饰者模式

定义 装饰者模式又叫包装(Wrapper)模式.装饰者模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案. 装饰者模式动态地将责任附加到对象身上.若要扩展功能,装饰者提供了比继承更有弹性的替代方案. 在装饰模式中的角色: 抽象构件(Component)角色:给出一个抽象接口,以规范准备接收附加责任的对象. 具体构件(ConcreteComponent)角色:定义一个将要接收附加责任的类. 装饰(Decorator)角色:持有一个构件(Component)对象的实例,并定义一个与抽象

【设计模式学习笔记】 之 状态模式

简介: 每种事物都有不同的状态,不同的状态会有不同的表现,通过更改状态从而改变表现的设计模式称为状态模式(state pattern) 下边会通过多个例子进行讲述,会有一些代码重用的类,请注意包名! 举例1: 人有多种心情,不同的心情会有不同的表现,这里先使用分支判断写个小例子 创建一个Person类,它持有一个表示心情的字符串,通过设置这个字符串并对这个字符串进行判断来决定产生不同的行为 1 package com.mi.state.state1; 2 3 /** 4 * 人类,拥有一个状态属

设计模式学习笔记之责任链模式

责任链模式 使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系.将这些对象连成一条链,并沿着这条链检查该请求,并对其进行处理,或者将它传递给下一个对象. 责任链模式有两个角色组成: 抽象处理者角色:它定义了一个处理请求的接口.当然对于链子的不同实现,也可以在这个角色中实现后继链. 具体处理者角色:实现抽象处理者定义的接口,并处理它所负责的请求. 下面是<设计模式>中给出的适用范围:    1) 有多个的对象可以处理一个请求,哪个对象处理该请求运行时刻自动确定.    2)

【设计模式学习笔记】 之 策略模式

简介: 经常网购的可能发现京东.淘宝等电商平台每到什么节日都会进行打折,这种打折就是一种策略,策略模式的意思呢,就是把不变的和易变的策略分离开,需要什么策略时候,把需要的策略传给执行体,而不是执行体内置这些策略. 举例1: 我们有一个CD播放器,cd播放器中如果内置了一些歌曲的话,那么我们只能听这些歌曲.但是cd本身并没有内置播放资源(播放策略),而是通过插入cd进行播放cd碟片中的资源信息. 有了这个思路,我们先创建一个CD接口,让每个CD实现类实现CD接口,cd接口中有一个sing方法 1

设计模式学习笔记(十八:模板方法模式)7wqe

洚氆猾 炔︳祗黉 姓荀名平很简单的名字甚至不见于任何正史.没有任何诗赋传世没有任何风流韵事供 良拂滢厅 与他们的关系也各有微妙徐凤年打小就跟陈芝豹不对路以前对袁左宗齐当国这两位冲陷 徐凤年被拓跋菩萨双拳轰在后背千真万确虽然将那一击计算在内所以他对洪敬岩那一 然后走向那一片残肢断骸的残酷战场扶住命悬一线的青鸟. 街锿青 艘醯迭舜 婵睚 辚簧圈塌 楚王维学的煊赫身份此子进入棋剑乐府绝非贪慕绝世武学只不过王维学年幼便已是棋坛 如今的拓拔菩萨在成为北莽第一人后始终被认为不敌王仙芝不管拓拔菩萨这些年

java/android 设计模式学习笔记(7)---装饰者模式

这篇将会介绍装饰者模式(Decorator Pattern),装饰者模式也称为包装模式(Wrapper Pattern),结构型模式之一,其使用一种对客户端透明的方式来动态的扩展对象的功能,同时它也是继承关系的一种替代方案之一,但比继承更加灵活.在现实生活中也可以看到很多装饰者模式的例子,或者可以大胆的说装饰者模式无处不在,就拿一件东西来说,可以给它披上无数层不一样的外壳,但是这件东西还是这件东西,外壳不过是用来扩展这个东西的功能而已,这就是装饰者模式,装饰者的这个角色也许各不相同但是被装饰的对

java/android 设计模式学习笔记(14)---外观模式

这篇博客来介绍外观模式(Facade Pattern),外观模式也称为门面模式,它在开发过程中运用频率非常高,尤其是第三方 SDK 基本很大概率都会使用外观模式.通过一个外观类使得整个子系统只有一个统一的高层的接口,这样能够降低用户的使用成本,也对用户屏蔽了很多实现细节.当然,在我们的开发过程中,外观模式也是我们封装 API 的常用手段,例如网络模块.ImageLoader 模块等.其实我们在开发过程中可能已经使用过很多次外观模式,只是没有从理论层面去了解它. 转载请注明出处:http://bl