`

Java设计模式之装饰模式

阅读更多
url:http://www.51cto.com/specbook/11/11650.htm
说明:
装饰模式是在不必改变原类文件和使用继承的情况下,动态的扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。

装饰模式的特点;
(1) 装饰对象和真实对象有相同的接口。这样客户端对象就可以以和真实对象相同的方式和装饰对象交互。
(2) 装饰对象包含一个真实对象的索引(reference)
(3) 装饰对象接受所有的来自客户端的请求。它把这些请求转发给真实的对象。
(4) 装饰对象可以在转发这些请求以前或以后增加一些附加功能。这样就确保了在运行时,不用修改给定对象的结构就可以在外部增加附加的功能。在面向对象的设计中,通常是通过继承来实现对给定类的功能扩展。

下表格列举了装饰模式和继承的不同:


装饰模式 VS 继承
装饰模式 继承
用来扩展特定对象的功能 用来扩展一类对象的功能
不需要子类 需要子类
动态地 静态地
运行时分配职责 编译时分派职责
防止由于子类而导致的复杂和混乱 导致很多子类产生,在一些场合,报漏类的层次
更多的灵活性 缺乏灵活性
对于一个给定的对象,同时可能有不同的装饰对象,客户端可以通过它的需要选择合适的装饰对象发送消息。 对于所有可能的联合,客户期望
很容易增加任何的 困难

例子:
让我们重新返回我们在工厂方法和单例模式log实用工具上,我们的模式主要由Logger 接口和两个它的实现类??FileLogger和ConsoleLogger??分别把信息出力到一个文件和屏幕中。另外,还有包括工厂方法的LoggerFactory类。
LoggerFactory没有出现在下图中,主要是因为它和现在讨论的例子没有直接联系。

让我们想象一些客户端需要以超出Logger Utility现在所提供的新的方式出力信息,客户端需要下面两种特征;
(1) 把出力的信息传唤为HTML文档
(2) 对出力信息进行逻辑转化的简单加密,在面向对象的设计中,不改变现存的类的代码,可以应用继承来增加新的功能。例如,子类化现在的类重载它的方法来增加所需要的新功能。

应用继承,我们要子类化FileLogger和ConsoleLogger类来增加新的功能,会有下面的一组新的子类:
子类 父类 功能
HTMLFileLogger FileLogger 转化出力信息为HTML文档,并存入一个Log文件
HTMLConsLogger ConsoleLogger 转化出力信息为HTML文档,并显示在屏幕上
EncFileLogger FileLogger 加密出力信息,并存入一个Log文件
EncConsLogger ConsoleLogger 加密出力信息,并显示在屏幕上

从类图可以看到,为了实现新的功能加入了一组新的子类。如果我们还有其他的Logger类型(例如:DBLogger出力信息到数据库中),这样会有更多子类。当一个新的特性需要被加入,子类的数量会有成倍数的增长,同时我们会有一个庞大的类层次。

装饰模式使我们从这种情景中解脱出来,装饰模式推荐通过对象的合成而不是继承来包装一个对象扩展它的功能。
应用装饰模式,让我们为Logger Utility定义一个有下列特征的默认根装饰类LoggerDecorator:

(1) LoggerDecorator包括一个Logger实例的引用。这个引用指向它包含的Logger对象。
(2) LoggerDecorator实现Logger借口、提供Log方法的基本的默认实现,他只是简单的转发调用给它包含的Logger 对象。每一个LoggerDecorator子类保证定义log方法。

Listing 19.1: LoggerDecorator Class

public class LoggerDecorator implements Logger { 
Logger logger; 
public LoggerDecorator(Logger inp_logger) { 
logger = inp_logger; 
} 
public void log(String DataLine) { 
/* 
Default implementation 
to be overriden by subclasses. 
*/ 
logger.log(DataLine); 
} 
}//end of class 
每一个logger的装饰定义log方法使很重要的,因为装饰对象必须提供和它包装的对象相同的借口。当客户端创建一个装饰类的实例,客户端以与装饰类交互方式和客户端与拥有相同接口原对象的交互方式是一致的。
让我们定义LoggerDecorator的两个子类,HTMLLogger和EncryptLogger。 #p# 具体的Logger 装饰类
HTMLLogger
HTMLLogger重载了log方法的默认实现。在log方法中,装饰类把出力信息转化为HTML文档,并且发送给可以出力的Logger实例。
Listing 19.2: HTMLLogger Class

public class HTMLLogger extends LoggerDecorator { 
public HTMLLogger(Logger inp_logger) { 
super(inp_logger); 
} 
public void log(String DataLine) { 
/* 
Added functionality 
*/ 
DataLine = makeHTML(DataLine); 
/* 
Now forward the encrypted text to the FileLogger 
for storage 
*/ 
logger.log(DataLine); 
} 
public String makeHTML(String DataLine) { 
/* 
Make it into an HTML document. 
*/ 
DataLine = "" + "" + DataLine + 
"" + ""; 
return DataLine; 
} 
}//end of class 
EncryptLogger
与HTMLLogger相似,EncryptLogger重载了log方法,在log方法中,EncryptLogger通过简单的将字符位置向右转移一位实现了加密逻辑,并且发送给可以出力的Logger实例。

Listing 19.3: EncryptLogger Class

public class EncryptLogger extends LoggerDecorator { 
public EncryptLogger(Logger inp_logger) { 
super(inp_logger); 
} 
public void log(String DataLine) { 
/* 
Added functionality 
*/ 
DataLine = encrypt(DataLine); 
/* 
Now forward the encrypted text to the FileLogger 
for storage 
*/ 
logger.log(DataLine); 
} 
public String encrypt(String DataLine) { 
/* 
Apply simple encryption by Transposition… 
Shift all characters by one position. 
*/ 
DataLine = DataLine.substring(DataLine.length() − 1) + 
DataLine.substring(0, DataLine.length() − 1); 
return DataLine; 
} 
}//end of class 

为了使用新设计装饰对象,客户端需要:
(1) 使用LoggerFactory工厂方法创建一个合适的Logger实例(FileLogger/ConsoleLogger)。
(2) 把第一步中创建的Logger实例作为参数转递给新创建的合适的LoggerDecorator实例的构造函数。
(3) 调用LoggerDecorator实例上的方法,

Listing 19.4: Client DecoratorClient Class

class DecoratorClient { 
public static void main(String[] args) { 
LoggerFactory factory = new LoggerFactory(); 
Logger logger = factory.getLogger(); 
HTMLLogger hLogger = new HTMLLogger(logger); 
//the decorator object provides the same interface. 
hLogger.log("A Message to Log"); 
EncryptLogger eLogger = new EncryptLogger(logger); 
eLogger.log("A Message to Log"); 
} 
}//End of class 
增加新的信息出力类型
在Logging Utility实例中,应用装饰模式对比使用继承不会因为类层次的增长而导致大量的子类,我们还有另外的Logger类型:DBLogger??出力信息到数据库中。为了将信息转化HTML格式或在出力到数据库以前对信息进行加密,客户端只需遵从上面提到的步骤,因为DBLogger是一种Logger类型,它可以作为构造函数的参数传递给HTMLLogger或EncryptLogger中任何一个类。

增加新的装饰
从例子中可以看到,LoggerDecorator实例包含了一个Logger类型了对象实例,在转发请求给Logger对象实例以前或以后,增加新的功能。因为LoggerDecorator类实现了Logger接口,LoggerDecorator实例或它的任何一个子类都可以作为一个Logger类型。因此LoggerDecortator包含它的任何子类的一个实例,并且将请求转发给它/。一般的一个装饰对象可以包含另一个装饰对象,并且可以向它转发请求。通过这种方式,新的装饰类,新的功能可以通过包装现存的装饰类来实现。


reference:
1.http://java.chinaitlab.com/model/768909_2.html
分享到:
评论

相关推荐

    JAVA设计模式之装饰模式代码

    在"JAVA设计模式之装饰模式代码"的示例中,我们可能会看到以下类结构: - `Component`:定义了装饰模式的基本接口,例如`Coffee`接口,包含了一些基本行为如`prepare()`。 - `Coffee`:实现了`Component`接口,代表...

    java设计模式之装饰模式

    装饰模式(Decorator Pattern)是Java设计模式中的一种结构型模式,它允许在运行时动态地向对象添加新的行为或职责,而不会破坏封装性。这种模式可以用来将多个功能组合在一起,同时保持类的可扩展性和灵活性。在...

    JAVA设计模式(java设计)

    Java设计模式是面向对象编程领域中的重要概念,它是一套被广泛接受并实践的解决软件设计问题的经验总结。设计模式并非具体的代码或库,而是一种在特定情境下为了解决常见问题而制定的通用解决方案的描述。它们描述了...

    Java 经典设计模式讲解以及项目实战

    Java 经典设计模式讲解以及项目实战 设计模式简介:主要介绍各种设计模式的概念和运用场景等 设计模式综合运用:主要是笔者在实际工作中运用到的一些设计模式综合运用事例的提炼 Spring设计模式简介:主要是讲述...

    Java设计模式之禅

    《Java设计模式之禅》是一本深入浅出讲解设计模式的书籍,书中不仅包含23种经典设计模式的案例,还详细介绍了设计模式背后的思想和原则,适合初学者以及对设计模式有一定了解的程序员阅读。本书旨在帮助读者理解如何...

    java设计模式之装饰者模式代码

    装饰者模式是面向对象设计模式的一种,主要用于动态地给一个对象添加一些额外的职责,而不会改变该对象的类。这种模式允许我们独立于对象的类来扩展对象的功能,为对象提供新的行为,同时保持了代码的可读性和可维护...

    java设计模式(刘伟)

    ### Java设计模式(刘伟) #### 一、引言 在《Java设计模式》这本书中,作者刘伟全面地介绍了24种经典的设计模式,并通过丰富的案例和代码示例进行了详细的解析。本书不仅适合初学者作为入门教材,也适合有一定...

    《java设计模式》课后习题模拟试题解答——刘伟.zip

    Java设计模式是软件工程中的一种最佳实践,它总结了在特定场景下解决常见问题的经验,为程序员提供了可重用的解决方案。本资料“《java设计模式》课后习题模拟试题解答——刘伟.zip”主要涵盖了Java设计模式的学习与...

    java设计模式ppt

    ### Java设计模式详解 在软件开发领域,设计模式是一种被广泛采用的解决方案,用来解决常见的设计问题。设计模式不仅能够帮助开发者写出可复用、可维护的代码,还能提高团队间的沟通效率。以下是对给定文件中提到的...

    《Java设计模式》课后答案-刘伟.rar

    《Java设计模式》是刘伟教授的一本关于设计模式的教材,主要面向高等学校的学生和对Java编程有深入兴趣的开发者。设计模式是软件工程中的一种重要思想,它封装了在特定场景下的问题解决方案,可以提高代码的可读性、...

    23种java设计模式.pdf

    " JAVA 设计模式概述" JAVA 设计模式是指在软件设计过程中,为了提高代码的可维护性、灵活性和可扩展性所使用的一些惯用解决方案。JAVA 设计模式可以分为三种:创建模式、结构模式和行为模式。 1. 创建模式 创建...

    《Java设计模式》刘伟 课后习题及模拟试题答案.rar

    《Java设计模式》是刘伟老师撰写的经典教材,它为Java程序员深入理解和应用设计模式提供了极佳的学习资源。设计模式作为软件工程中解决特定问题的典型方案,是每一个有志于成为高级开发者的程序员不可或缺的知识储备...

    java设计模式.高清影印版

    Java设计模式是软件工程中的一种最佳实践,它提供了一套标准的解决方案,用于解决在编写可维护、可扩展和高效代码时经常遇到的问题。这些模式是经验丰富的开发者们在面对相似问题时,经过反复试验和优化后总结出的...

    重学java的设计模式

    Java作为一门广泛应用的开发语言,其设计模式的应用对于提高代码质量、可维护性和可扩展性至关重要。本文将着重探讨创建型模式、结构型模式和行为模式这三大类设计模式,并结合六项设计原则进行深入解析。 首先,...

    java设计模式课程设计

    使用5种设计模式完成的一个点单系统,显示不同系列下的所有商品,点击选择冰度甜度之后添加到订单中,计算总金额,下单之后发送订单到门店的后厨制作商品。使用了抽象工厂模式、装饰模式、单例模式、代理模式、原型...

    Head First 设计模式 +Java设计模式(第2版)

    《Head First 设计模式》与《Java设计模式(第2版)》是两本非常重要的IT书籍,专注于软件开发中的设计模式。设计模式是解决软件设计中常见问题的经验总结,它们提供了一种标准的方法来处理特定场景下的问题,使得代码...

    设计模式--装饰者模式java例子

    装饰者模式是软件设计模式中的一种结构型模式,它...综上所述,装饰者模式在Java编程中是一种重要的设计模式,尤其适用于需要动态添加或删除对象功能的场景。通过以上示例和解释,我们可以更好地理解和应用装饰者模式。

    java设计模式的应用

    ### Java设计模式的应用 #### 一、引言 在当今快速发展的软件开发领域,Java作为一门功能强大且灵活的语言,不仅拥有丰富的API资源,还能与强大的数据库系统无缝对接。这使得许多开发人员能够以模块化的形式构建...

Global site tag (gtag.js) - Google Analytics