一、功能描述
装饰者模式可以在运行时期动态的扩展一个类对象的功能,向一个类对象而不是类增加额外的功能。装饰者模式可以看做是继承的替代,两者的不同处是:继承是在编译期间增加类(不是对象)的功能,而装饰者模式则是在运行时动态的添加功能到单个对象。
二、实现描述
动态的向一个对象添加功能是由称之为装饰者的类来完成的,在创建这个装饰者的类的过程中,需要将原始被包装对象当做参数传递给装饰者的构造器。然后由这个装饰器利用原始类提供的基本功能进而实现额外的功能,需要注意的是装饰器的类必须与原始类具有相同接口。
三、实现过程
这里用一个例子来描述实现过程。假设我们有一个实现了Window接口的窗口类,现在我们需要对这个窗口增加一个滚动功能,也就是需要在窗口上增加水平跟竖直滚动条,在Window接口中并没有增加滚动条功能的方法,要实现这个功能,我们可以写一个这个窗口类的子类ScrollingWindow,在这个子类中将窗口滚动功能加上,或者我们可以写一个具有滚动功能的装饰器类ScrollingWindowDecorator,然后将这个装饰器类动态的将这个功能增加到一个已存在的Window对象中。这么看来,这两种方式都可以。
如果我们想增加边界功能到
Window上并且Window没有提供增加边界的方法
。这时,对于
ScrollingWindow这种实现方式来说,我们想增加边界到Window上,我们必须创建两个子类分别是:WindowWithBorder
和
ScrollingWindowWithBorder。很明显,如果我们还想增加功能的时候这个问题就会引起类爆炸的问题。而对于装饰者这种实现方式,我们仅仅增加一个具有边界功能的装饰类BorderedWindowDecorator
即可。这样运行时,我们可以用
BorderedWindowDecorator或者
ScrollingWindowDecorator来装饰已存在的窗口对象或者两个装饰器同时使用。
四、具体实现
参考上面的例子,一步步实现这个装饰器模式
// the Window interface
interface Window {
public void draw(); // draws the Window
public String getDescription(); // returns a description of the Window
}
// implementation of a simple Window without any scrollbars
class SimpleWindow implements Window {
public void draw() {
// draw window
}
public String getDescription() {
return "simple window";
}
}
- 定义装饰器的抽象类,所有的装饰器都会继承该抽象类,这个抽象类需要实现Window接口。
// abstract decorator class - note that it implements Window
abstract class WindowDecorator implements Window {
protected Window decoratedWindow; // the Window being decorated
public WindowDecorator (Window decoratedWindow) {
this.decoratedWindow = decoratedWindow;
}
}
// the first concrete decorator which adds vertical scrollbar functionality
class VerticalScrollBarDecorator extends WindowDecorator {
public VerticalScrollBarDecorator (Window decoratedWindow) {
super(decoratedWindow);
}
public void draw() {
drawVerticalScrollBar();
decoratedWindow.draw();
}
private void drawVerticalScrollBar() {
// draw the vertical scrollbar
}
public String getDescription() {
return decoratedWindow.getDescription() + ", including vertical scrollbars";
}
}
// the second concrete decorator which adds horizontal scrollbar functionality
class HorizontalScrollBarDecorator extends WindowDecorator {
public HorizontalScrollBarDecorator (Window decoratedWindow) {
super(decoratedWindow);
}
public void draw() {
drawHorizontalScrollBar();
decoratedWindow.draw();
}
private void drawHorizontalScrollBar() {
// draw the horizontal scrollbar
}
public String getDescription() {
return decoratedWindow.getDescription() + ", including horizontal scrollbars";
}
}
public class DecoratedWindowTest {
public static void main(String[] args) {
// create a decorated Window with horizontal and vertical scrollbars
Window decoratedWindow = new HorizontalScrollBarDecorator (
new VerticalScrollBarDecorator(new SimpleWindow()));
// print the Window's description
System.out.println(decoratedWindow.getDescription());
}
}
五、组成结构
装饰者模式的组织结构可以由下面的图来说明:
下面分别介绍图中元素:
为被装饰的对象定义的接口。
被装饰对象的接口实现类。
维持一个Component对象的引用,并与Component接口保持一致(继承这个接口)
代表固定功能的装饰器类。
六、java类库中使用装饰者模式的例子
在java类库中,大量的用到了装饰者模式,其中最突出的就是在java.io包中了。一开始我们学习java的io流的时候,可能看到这么多的类会一头雾水,但是,只要理解了装饰者模式,那么对于io包中的类便会一目了然了。比如说:FileInputStream类,就是一个被装饰的对象类,我们可以用BufferedInputStream去装饰它,也可以用LineNumberInputStream去装饰它,当然也可以两者一起来装饰。BufferedInputStream和LineNumberInputStream都继承自FilterInputStream,而FilterInputStream是一个抽象的装饰类。
下面这个图能更好的理解java的io包中的类的组织形式:
- 大小: 23.8 KB
- 大小: 53.7 KB
分享到:
相关推荐
java设计模式之装饰者模式代码
Qt设计模式之装饰者模式
设计模式之装饰者模式,极客学院VIP课堂的课件,装饰者模式的示例
javascript设计模式之装饰者模式.docx
装饰者模式是在不改变原有类和不使用继承的情况下,动态地扩展一个对象的功能,代码中通过对象参数进行选择。
设计模式--装饰者模式java例子
// 第10步:执行RedBalls对象的decorate方法总结装饰者模式是为已有功能动态地添加更多功能的一种方式,把每个要装饰的功能放在单独的函数里,然后用
c# ,设计模式,装饰者模式,星巴兹咖啡,基本上就是head first 上的例子的C#实现,根据自己的理解,作了一点点改动,可以直接运行。
设计模式—装饰者模式
设计模式—装饰者模式,介绍的非常详细,讲解透彻
NULL 博文链接:https://jacky-dai.iteye.com/blog/1132229
设计模式 - 装饰者模式
软件设计模式之装饰模式讲解ppt,可用于教学课件。
54-Spring设计模式之装饰器模式1
Java 经典设计模式讲解以及项目实战 设计模式简介:主要介绍各种设计模式的概念和运用场景等 设计模式综合运用:主要是笔者在实际工作中运用到的一些设计模式综合运用事例的提炼 Spring设计模式简介:主要是讲述...
设计模式 c# 装饰模式
使用PHP实现的设计模式之装饰者模式,希望对您的开发有所启发。
设计模式主要分为三大类: 1.创建型模式:工厂模式、抽象工厂模式、单例模式、建造者模式、原型模式。 2.结构型模式:适配器模式、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式。 4.行为型模式:...