专业的JAVA编程教程与资源

网站首页 > java教程 正文

Java设计模式学习总结:装饰模式

temp10 2024-11-26 08:54:26 java教程 13 ℃ 0 评论

一、概述

装饰模式又名包装(Wrapper)模式。装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案,它通过一种无须定义子类的方式给对象动态增加职责,使用对象之间的关联关系取代类之间的继承关系。装饰模式可以在不改变一个对象本身功能的基础上给对象增加额外的新行为。

Java设计模式学习总结:装饰模式


通常情况下,扩展一个类的功能会使用继承方式来实现。但继承具有静态特征,耦合度高,并且随着扩展功能的增多,子类会很膨胀。如果使用组合关系来创建一个包装对象(即装饰对象)来包裹真实对象,并在保持真实对象的类结构不变的前提下,为其提供额外的功能,这就是装饰模式的目标。

引入了装饰类,在装饰类中既可以调用待装饰的原有类的方法,还可以增加新的方法,以扩展原有类的功能,装饰模式的应用场景:

1、需要扩展一个类的功能,或给一个类增加额外行为。

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

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

二、装饰模式的定义

装饰模式:动态地给一个对象增加一些额外的职责。就扩展功能而言,装饰模式提供了一种比使用子类更加灵活的替代方案。Decorator Pattern: Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality.


Component(抽象构件)

ConcreteComponent(具体构件)

Decorator(抽象装饰类)

ConcreteDecorator(具体装饰类)

public abstract class Component {

public abstract void operation();

}

public class ConcreteComponent extends Component {

public void operation() {

//实现基本功能

}

}

public class Decorator extends Component {

private Component component; //维持一个对抽象构件对象的引用

//注入一个抽象构件类型的对象

public Decorator(Component component) {

this.component=component;

}

public void operation() {

component.operation(); //调用原有业务方法

}

}

public class ConcreteDecorator extends Decorator {

public ConcreteDecorator(Component component) {

super(component);

}

public void operation() {

super.operation(); //调用原有业务方法

addedBehavior(); //调用新增业务方法

}

//新增业务方法

public void addedBehavior() {

……

}

}

三、装饰模式的案例

本资料案例主要学习 《Java设计模式 中南大学 刘伟》之后总结,其中程序学习总结者亲自在myEclipse8.5版本调试通过,注意在这里所有的类和接口写在一个Java文件里面,除了主类其它类和接口不能声明为public的,主要是提醒出道时间不长的读者,以免造成学习上的麻烦,但重在多试,有问题是好事。

案例描述如下:

某软件公司基于面向对象技术开发了一套图形界面构件库——VisualComponent,该构件库提供了大量基本构件,如窗体、文本框、列表框等,由于在使用该构件库时,用户经常要求定制一些特殊的显示效果,如带滚动条的窗体、带黑色边框的文本框、既带滚动条又带黑色边框的列表框等等,因此经常需要对该构件库进行扩展以增强其功能,现使用装饰模式来设计该图形界面构件库。


说明:

(1) Component:抽象界面构件类,充当抽象构件类

(2) Window:窗体类,充当具体构件类

(3) TextBox:文本框类,充当具体构件类

(4) ListBox:列表框类,充当具体构件类

(5) ComponentDecorator:构件装饰类,充当抽象装饰类

(6) ScrollBarDecorator:滚动条装饰类,充当具体装饰类

(7) BlackBorderDecorator:黑色边框装饰类,充当具体装饰类

package com.test;

public class Test {

public static void main(String[] args) {

//使用抽象构件定义全部对象

Component component, componentSB, componentBB;

component = new Window();//创建具体构件对象

//创建装饰后的构件对象

componentSB = new ScrollBarDecorator(component);

//将装饰了一次的对象注入另一个装饰类中,进行第二次装饰

componentBB = new BlackBorderDecorator(componentSB);

componentBB.display();

}

}

abstract class Component {

public abstract void display();

}

class Window extends Component {

public void display() {

System.out.println("显示窗体!");

}

}

class TextBox extends Component {

public void display() {

System.out.println("显示文本框!");

}

}

class ListBox extends Component {

public void display() {

System.out.println("显示列表框!");

}

}

class ComponentDecorator extends Component {

private Component component; //维持对抽象构件类型对象的引用

//注入抽象构件类型的对象

public ComponentDecorator(Component component) {

this.component = component;

}

public void display() {

component.display();

}

}

class ScrollBarDecorator extends ComponentDecorator {

public ScrollBarDecorator(Component component) {

super(component);

}

public void display() {

this.setScrollBar();

super.display();

}

public void setScrollBar() {

System.out.println("为构件增加滚动条!");

}

}

class BlackBorderDecorator extends ComponentDecorator {

public BlackBorderDecorator(Component component) {

super(component);

}

public void display() {

this.setBlackBorder();

super.display();

}

public void setBlackBorder() {

System.out.println("为构件增加黑色边框!");

}

}

运行结果:

模式优点:

(1)对于扩展一个对象的功能,装饰模式比继承更加灵活,不会导致类的个数急剧增加;当不能采用继承的方式对系统进行扩展或者采用继承不利于系统扩展和维护时可以使用装饰模式。

(2)可以通过一种动态的方式来扩展一个对象的功能,通过配置文件可以在运行时选择不同的具体装饰类,从而实现不同的行为;在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。

(3)可以对一个对象进行多次装饰。

(4)具体构件类与具体装饰类可以独立变化,用户可以根据需要增加新的具体构件类和具体装饰类,且原有类库代码无须改变,符合开闭原则。

模式缺点:

(1)使用装饰模式进行系统设计时将产生很多小对象,大量小对象的产生势必会占用更多的系统资源,在一定程度上影响程序的性能。

(2)比继承更加易于出错,排错也更困难,对于多次装饰的对象,调试时寻找错误可能需要逐级排查,较为繁琐。

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表