您的位置:首页 > 编程语言 > Java开发

简单Java代码实例助你通俗易懂的理解什么是装饰(者)设计模式 (Decorator)

2016-11-24 15:34 1011 查看
首先抛开到处都有的文字概念。来看下面的例子。

现在以:人吃饭。这个需求为例。来讲解这个设计模式。

1.0:想当年,人们都比较朴实。吃饭就是简简单单的吃饭。

那么PersonBefore类里面一个简单的方法chifan();

2.0:现如今,人们生活水平高了。吃饭的花样也多了,简单的吃饭已经不能满足需求。

那么怎么修改原来的代码才合适呢。总不能分分钟推到重构吧。

先看下面代码实现:

PersonBefore类,最原始的需求实现。

package com.lxk.designPattern.decorator;

/**
* 被装饰的类
* (被增强对象)
* <p>
* Created by lxk on 2016/11/24
*/
public class PersonBefore {
public void eat() {
System.out.println("吃饭");
}
}


PersonNow类,需求增强之后的实现类。

package com.lxk.designPattern.decorator;

/**
* 装饰类
* (要去增强目标对象的类)
* 装饰类通常会通过构造方法接收被装饰的对象。
* 并基于被装饰的对象的功能,提供更强的功能。
* <p>
* Created by lxk on 2016/11/24
*/
public class PersonNow {
private PersonBefore p;

PersonNow(PersonBefore p) {
this.p = p;
}

public void superChifan() {
//简单扩展
System.out.println("开胃酒");
p.eat();
System.out.println("甜点");
System.out.println("来一根烟");
}
}

PersonDemo类,需求实际被调用的类。
package com.lxk.designPattern.decorator;

/**
* 装饰设计模式:
* 当想要对已有的对象进行功能增强时,
* 可以定义类,将已有对象传入,基于已有的功能,并提供加强功能。
* 那么自定义的该类称为装饰类。
* <p>
* 装饰类通常会通过构造方法接收被装饰的对象。
* 并基于被装饰的对象的功能,提供更强的功能。
*/

class PersonDemo {
public static void main(String[] args) {
PersonBefore p = new PersonBefore();
//p.eat();//这个是需求1.0
PersonNow sp = new PersonNow(p);
sp.superChifan();
}
}


此代码只为简单易懂的理解这个装饰者设计模式。你可能会考虑到使用继承也可以实现类似效果,继承和装饰模式之间有什么差别呢?那是后话了。再说吧。

我还想问这个装饰者设计模式和代理模式的区别呢?和AOP的差别在哪?

下面是摘自某度文库的--装饰模式的概念的详细文字描述。真不是分分钟能明白说的都是啥。

装饰模式:

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

装饰模式的特点

(1) 装饰对象和真实对象有相同的接口。这样客户端对象就能以和真实对象相同的方式和装饰对象交互。

(2) 装饰对象包含一个真实对象的引用(reference)

(3) 装饰对象接受所有来自客户端的请求。它把这些请求转发给真实的对象。

(4) 装饰对象可以在转发这些请求以前或以后增加一些附加功能。这样就确保了在运行时,不用修改给定对象的结构就可以在外部增加附加的功能。在面向对象的设计中,通常是通过继承来实现对给定类的功能扩展。

适用性

以下情况使用Decorator模式

1. 需要扩展一个类的功能,或给一个类添加附加职责。

2. 需要动态的给一个对象添加功能,这些功能可以再动态的撤销。

3. 需要增加由一些基本功能的排列组合而产生的非常大量的功能,从而使继承关系变的不现实。

4. 当不能采用生成子类的方法进行扩充时。一种情况是,可能有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。另一种情况可能是因为类定义被隐藏,或类定义不能用于生成子类。

优点

1. Decorator模式与继承关系的目的都是要扩展对象的功能,但是Decorator可以提供比继承更多的灵活性。

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

缺点

1. 这种比继承更加灵活机动的特性,也同时意味着更加多的复杂性。

2. 装饰模式会导致设计中出现许多小类,如果过度使用,会使程序变得很复杂。

3. 装饰模式是针对抽象组件(Component)类型编程。但是,如果你要针对具体组件编程时,就应该重新思考你的应用架构,以及装饰者是否合适。当然也可以改变Component接口,增加新的公开的行为,实现“半透明”的装饰者模式。在实际项目中要做出最佳选择。

实际使用

java IO 流是典型的装饰模式。

这倒是真的,看前2篇 BufferedReader BufferedWriter 都是把字符读写流资源作为参数,传进类内部,对其进行功能增强。使得读写的效率得到提高。果然是实际使用此模式的好例子。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: