GOF的设计模式,讲的很细,我这里都很粗略。什么意图,别名,参与者,结构,协作,效果等等。。。
我这等小民,也没有那么高深的理论,拾人牙慧就满足了。
模式是死的,运用是活的。
今天讲讲装饰器模式。其实 每个模式的名字都很重要,因为这个名字基本就说明了这个模式用来干什么。当然,装饰器,不是用来装饰的,但是和装饰相关。
比如,我们设计一个窗子,完了,觉得太单调,于是重新加上边框,还觉得单调,那就贴点窗纸吧,如果还是不满意,那么可以糊个纱窗……
如果用程序来实现,我们可能想到这些对象,窗子,加边框的窗子,贴窗纸的窗子(好拗口),加边框贴窗纸的窗子…… 其实这种错误只会在初学者身上犯。
首先,我们的对象的粒度,应该合适,这样通过面向对象的重复利用,组合,就可以实现很多奇怪的东西。这里,我们有必要把窗,窗纸,边框,窗纱等看单独的对象,再细分,发现,其他都是作为装饰品,为窗服务的。于是,一个大概的参与者思路就清晰了。
然后,如何组织这些类呢?由于他们都与窗有关,那么,肯定又一个共同点,我们可以抽象成一个接口。然后,窗,与其他的东西又不一样,那么又可以分别对待。
最后,我们大概可以得出一个结构图了。这里使用标准的装饰器模式的UML:
图中的Component,应该就是要装饰的对象的抽象,注意,饰品也是可以被装饰的,但是必须有一实际的被装饰对象(下面会说明为什么)。
Decorator接口把装饰器隔离出来,表明这些是装饰器。
每个装饰器需要一个可装饰的 被装饰对象,这就是ConcreteComponent了。为了强制要求装饰器必须装饰一个可装饰对象,我们在构造函数里做了要求。
下面就来看一个小例子。本例子完全只是为了说明模式的结构运用,实际的情况只能如有雷同,实属巧合。
一个接口,这是可被装饰对象的统一接口,表明他们能做什么。
public interface VisualComponent {
public void draw();
}
这是一个可视组件。他的方法就是画出自己。也可以使用抽象类。
某些组件可能有共同的方法。这里为了简化,直接说关键。
public class Pane implements VisualComponent{
@Override
public void draw() {
// TODO Auto-generated method stub
System.out.println("drawing pane...");
}
}
这是一块面板,我们省略了绘制过程,并打印出一串字符,表示正在绘制此组件。
接下来,我们就要给这个可视化组件做装饰了。当然,不仅仅是Pane可以被装饰,只要是实现了VisualComponent接口的类都可以被装饰。
首先要有一个装饰器的接口。
public abstract class ComponentDecorator implements VisualComponent{
protected VisualComponent visualComponent ;
public ComponentDecorator(VisualComponent vc){
this.visualComponent = vc;
}
}
这里使用了抽象类,如果使用接口也可以,直接继承 VisualComponent就行。
之所以使用抽象类,是为了确保子类使用父类的构造函数来完成装饰器应有的职责,那就是我们只是装饰者,应该提供一个被装饰者给我。
接下来,是具体的装饰器了,我们定义两个,这样可以看到使用情况。
首先是一个边框装饰器。
public class BorderDecorator extends ComponentDecorator{
public BorderDecorator(VisualComponent vc){
super(vc);
}
@Override
public void draw() {
// TODO Auto-generated method stub
visualComponent.draw();
System.out.println("draw bording...");
}
}
可以看到,他所装饰的类,是通过继承父类构造函数来实现的。
在绘制时,我们先绘制父类,然后绘制自己(代码中省略)。
然后再来一个头装饰器,也就是绘制一个顶栏的装饰器。
public class HeaderDecorator extends ComponentDecorator{
public HeaderDecorator(VisualComponent vc){
super(vc);
}
@Override
public void draw() {
// TODO Auto-generated method stub
visualComponent.draw();
System.out.println("drawing header...");
}
}
好了,我们的装饰器好了,现在来看看如何使用。
装饰器模式,通过不同的修饰顺序,我们可以得到不同的结果。这里如何组装,
是使用者决定的。
public class TestMain {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
VisualComponent vc = new Pane();
VisualComponent newVC = new HeaderDecorator(new BorderDecorator(vc));
newVC.draw();
}
}
看着是不是眼熟,这个其实和java中的I/O很眼熟;
InputStream ins = new BufferedInputStream(new FileInputStream("xx.txt"));
没错,java.io 下的类就是使用了装饰器模式(当然还有其他的比如Adapter)
从网上找到一张图,很能说明问题,相信大家看完以后,对 java.io里的那么多类,会有一个新的认识。
这个图好像是《Head First 设计模式》的吧。。。嘿嘿,我也没看这本书,但是风格很像。
到这里,我们对装饰器模式应该有个大概的认识了。这里,也可以看到,装饰器模式,其实很适合用于链式过滤,每一层都灵活控制。
这点很像OSI的七层协议,每一层,都添加一个头(做个装饰)。
我们也看看自己有什么设计上需要用到装饰器模式的吧,赶快动手试试效果。
- 大小: 8.6 KB
- 大小: 47.8 KB
分享到:
相关推荐
而Qt4作为一个强大的开源库,提供了丰富的功能,使得开发者能够在多个操作系统上构建用户界面和应用程序。 首先,我们要理解设计模式的基本类型,包括创建型、结构型和行为型模式。创建型模式如单例模式(Singleton...
- 装饰模式(Decorator):动态地给一个对象添加一些额外的职责。 - 享元模式(Flyweight):使用共享对象,有效地支持大量细粒度的对象。 3. **行为型模式**:这类模式关注对象之间的责任分配。 - 责任链模式...
代理模式(Proxy Pattern)、单例模式(Singleton Pattern)、工厂方法...模式(Decorator Pattern)、迭代器模式(Iterator Pattern)、组合模式(Composite Pattern)、观察者模式(Observer Pattern)、责任链模式...
`vue-property-decorator`是一个库,它是Vue.js和TypeScript的结合,提供了装饰器来帮助我们在TypeScript中更好地声明和管理组件的属性。它使得我们可以利用TypeScript的强类型系统,提高代码的可维护性和可读性。...
【Decorator模式】是一种设计模式,它允许在运行时动态地给对象添加新的责任或功能,而不必通过子类化的方式。在上述的奇幻RPG游戏中,Decorator模式被用来实现武器的锻造过程,尤其是武器镶嵌宝石的功能。这个过程...
C#设计模式(12)-Decorator Pattern C#设计模式(11)-Composite Pattern C#设计模式(10)-Adapter Pattern C#设计模式(9)-Prototype Pattern C#设计模式(8)-Builder Pattern C#设计模式(7)-Singleton...
装饰模式(Decorator Pattern)是一种结构型设计模式,它允许你向一个现有的对象添加新的功能,同时又不改变其结构。装饰模式通过创建一个装饰类,该类包装了原始类的实例,并在调用原始类方法之前或之后添加额外的...
Decorator模式,也称为装饰模式,是设计模式中的一个重要组成部分,它在不改变原有对象接口的前提下,动态地给对象添加新的功能,从而扩展了对象的能力。这篇博客()将深入探讨这个模式的细节。 装饰模式的核心...
设计模式是软件工程领域中一个非常重要的话题,它为解决常见的软件设计问题提供了标准化的方法。本书《C++设计模式》聚焦于GoF(Gang of Four)所提出的23种设计模式,并通过C++语言进行深入解析和实现。通过本书的...
这个“JAVA设计模式-chm版”资源显然包含了关于Java设计模式的详细信息,便于理解和应用。设计模式是对常见问题的解决方案的标准化描述,它们在软件工程中起到了重要的作用,帮助开发者创建可维护、可扩展且易于理解...
在完成所有设计模式的学习和解析之后,开发者会发现自己已经进入了一个新的境界。这个过程不仅是对知识的掌握,更是对思维方式的一种转变。设计模式的学习过程往往充满挑战,但同时也充满了成就感。 #### 1. 创建型...
例如,单例模式利用了静态成员和私有构造函数,确保类只有一个实例;工厂模式通过抽象工厂接口实现对象的延迟创建,提供了一种解耦对象创建和使用的机制;策略模式利用接口或抽象类定义策略,使得在运行时可以动态...
- 装饰模式(Decorator):动态地给一个对象添加一些额外的职责,提供比继承更灵活的功能扩展。 3. 行为型模式(Behavioral Patterns): - 责任链模式(Chain of Responsibility):避免将处理请求的发送者和...
工厂模式是一种创建型设计模式,它提供了一个接口,用于创建对象,但允许子类决定实例化哪个类。这在C#中尤其有用,当需要动态地根据条件创建不同类型的对象时。 3. 抽象工厂模式(Abstract Factory): 抽象工厂...
设计模式是软件工程中的一种最佳实践,它是在特定上下文中解决常见问题的模板。这个压缩包文件名为"26种设计模式",其中可能详细介绍了软件开发中的26个核心设计模式。这些模式是经过时间检验、被广泛接受并反复使用...
- **定义**:动态地给一个对象添加一些额外的职责,就增加功能来说,Decorator模式相比生成子类更加灵活。 - **应用场景**:需要扩展一个类的功能,或给一个类添加附加责任。 - **优点**:比继承更加灵活,可以在...
《设计模式-王翔 全本》是一本深入探讨软件设计模式的重要著作,作者王翔在书中详尽地阐述了设计模式的理论基础与实践应用。设计模式是软件工程中的重要概念,它代表了在特定情境下,经过时间检验、可复用的解决方案...
例如,适配器模式(Adapter)用于将不兼容接口的对象连接起来,装饰器模式(Decorator)允许动态地给对象添加新的行为或职责,代理模式(Proxy)提供一个代表对象来控制对原对象的访问。 3. 行为型模式:这类模式...