`
cljspn
  • 浏览: 46938 次
  • 性别: Icon_minigender_1
  • 来自: 长春
最近访客 更多访客>>
社区版块
存档分类
最新评论

设计模式之--进行硬编码的静态装饰器模式和装饰器模式链化

阅读更多

动态代理的背后思想是在一个对象的周围插入动态的行为但不改变对象的已有代码和接口。装饰器模式提供一种不必改变对象代码就可以装饰一个对象(改变它的行为)并向其增加横切面的方法。现在就用静态的装饰来实现具体的业务功能

首先有一个简单业务接口:

public interface IMyBusinessObject { 
      public String doExecute(String in); 
} 

 这个接口有一个业务对象类的实现。

public class MyBusinessObject implements IMyBusinessObject { 
public String doExecute(String in) { 
System.out.println("Here in MyBusinessObject doExecute: input :" + in); 
return in; 
} 
} 

 

现在想要在这个业对象类的方法doExecute之前与之后增加一些行为,装饰器模式使我们十分容易增加这个功能。现在定义一个抽象类,这个抽象类实现上面的业务接口。

public abstract class ADecorator implements IMyBusinessObject { 
      protected IMyBusinessObject target; 
  
      public void setTarget(IMyBusinessObject target) { 
            this.target = target; 
      } 
  
public ADecorator(){}; 
  
      public ADecorator(IMyBusinessObject target_) { 
            setTarget(target_); 
      } 
} 

 

为什么要把设置业务对象的方法放到抽象类中呢,这也是重构的一种方法。就是把子类中设置业务对象的方法提到父类中。术语为方法上移。 现在定义一个从ADedorator扩展来的具体类DebugConcreteDecorator,目的是在我们业务对象被调用之前和之后加入一些调试信息:

public class DebugConcreteDecorator extends ADecorator { 
  
  
      public DebugConcreteDecorator(IMyBusinessObject target_) { 
            super(target_); 
      } 
  
      public String doExecute(String in) { 
            System.out 
                        .println("DebugConcreteDecorator: before method : doExecute "); 
            String ret = target.doExecute(in); 
            System.out.println("DebugConcreteDecorator: after method : doExecute "); 
            return ret; 
      } 
} 

 

现在在客户端,我们调用业务对象:

IMyBusinessObject aIMyBusinessObject = new MyBusinessObject(); 
IMyBusinessObject wrappedObject = new DebugConcreteDecorator( 
aIMyBusinessObject); 
wrappedObject.doExecute("Hello World"); 

 输出结果如下:

DebugConcreteDecorator: before method : doExecute 
Here in MyBusinessObject doExecute: input :Hello World 
DebugConcreteDecorator: after method : doExecute 

实际的业务方法调用之前链化装饰器----调用一个装饰器后再调用另一个装饰器。让我们再定义另一个装饰器去展示这个方法:

public class AnotherConcreteDecorator extends ADecorator { 
  
      public AnotherConcreteDecorator( 
                  IMyBusinessObject target_) { 
            super(target_); 
      } 
  
      public String doExecute(String in) { 
            System.out 
                        .println("AnotherConcreteDecorator: Going to execute method : doExecute"); 
            in = in + " Modified by AnotherConcreteDecorator"; 
            String ret = target.doExecute(in); 
            System.out 
                        .println("AnotherConcreteDecorator: After execute method : doExecute"); 
            return ret; 
      } 
  
} 

 

上面的代码片段通过在业务方法输入的字符参数后增加(" Modified by AnotherConcreteDecorator")字符串,从而实现对其进行了修改。如果我们想链化装饰器,在客户端,我们可以编写如下的代码:

 

IMyBusinessObject aIMyBusinessObject = new MyBusinessObject(); 
IMyBusinessObject wrappedObject = new AnotherConcreteDecorator( 
            new DebugConcreteDecorator(aIMyBusinessObject)); 
wrappedObject.doExecute("Hello World"); 

 

在上面的代码片段中,我在创建一个DebugConcreteDecorator实例时,向其传递了一个实际的业务对象实例。然后用一个刚才定义的notherConcreteDecorator实例去包装DebugConcreteDecorator实例。AntherConcreteDecorator首先在输入参数后增加字符串对其进行修改,然后调用DebugConcreteDecorator实例的doExecute()方法。这时,DebugConcreteDecorator会记录doExectute()方法的输出的条目,然后调用doExecute()去调用实际业务对象的doExecute()方法。
它的返回路径以相反的顺序。在从实际的业务对象(MyBusinessObject)doExecute()方法返回之后,DebugConcreteDecorator余下代码将被执行。于是,调用返回至AnotherConcreteDecorator实例并执行余下的部份代码。

输出结果如下:

AnotherConcreteDecorator: Going to execute method : doExecute 
DebugConcreteDecorator: before method : doExecute 
Here in MyBusinessObject doExecute: input :Hello World Modified by AnotherConcreteDecorator 
DebugConcreteDecorator: after method : doExecute 
AnotherConcreteDecorator: After execute method : doExecute 

 

静态装饰器有一个问题:不知大家注意到没有DebugConcreteDecorator 或 AnotherConcreteDecorator中doExecute()方法。它对目标对象doExecute()方法的调用进行了硬编码。并且,如果我们在IMyBusinessObject接口中定义另一个方法,我们必须改写所有装饰器并提供这个方法的实现。于是,在实践中,我们可能会因有许多装饰器和在每个装饰器中有大量的代码而止步。

下一篇博客用一个动态代理可以帮助我们去掉这些硬编码,此外,我们不必在每个装饰器去实现和改写业务接口中的每个方法。

分享到:
评论
1 楼 rasonyang 2008-02-18  
非常实用!

相关推荐

    《设计模式--基于C#的工程化实现及扩展》.(王翔)_《0528》.rar

    《设计模式--基于C#的工程化实现及扩展》是一本深入探讨软件设计模式的书籍,作者王翔通过C#语言来阐述各种设计模式的工程化应用和拓展。设计模式是软件开发中的一种最佳实践,它总结了在特定场景下解决常见问题的...

    Head.First设计模式--22~39.rar.pdf (C#)

    17. **职责链模式**(Chain of Responsibility):37章涉及职责链模式,它避免了硬编码的接收者和发送者之间的关联。C#中的职责链模式常用于事件处理和请求分发。 18. **命令模式**(Command):38章介绍了命令模式...

    C嵌入式编程设计模式例程-5

    在C语言中,这通常通过静态初始化和一个全局指针来实现。 2. **工厂模式**: 当需要动态创建对象,但又希望隐藏实际创建过程时,工厂模式非常有用。在嵌入式系统中,可能有多种硬件平台,每种平台需要创建不同类型的...

    Java 设计模式最佳实践

    Java 设计模式最佳实践是软件开发中的重要主题,它涵盖了多种模式,这些模式已被广泛接受并应用于实际项目中,以解决常见的编程问题和提升代码的可读性、可维护性和可扩展性。在这个主题中,我们将深入探讨一些关键...

    侯捷的最新设计模式讲义

    这份讲义由知名IT专家侯捷编撰,旨在帮助开发者理解和掌握设计模式这一核心编程概念,提升软件设计与架构能力。 设计模式是软件工程中经过实践验证的、在特定情境下解决常见问题的可复用解决方案。它们反映了软件...

    C#设计模式PDF,主要介绍如何用最常见的设计模式写C#程序。

    以上只是C#设计模式中的一部分,PDF文档可能还会涵盖如享元模式、门面模式、责任链模式、迭代器模式、组合模式、备忘录模式、解释器模式等其他模式。每个模式都有其特定的适用场景和优缺点,理解并熟练运用这些模式...

    C#设计模式C#设计模式

    在C#中,我们可以使用抽象工厂类或者接口来定义产品的创建过程,而具体的实现则由子类来完成,这样可以避免代码硬编码特定类的实例化,增加了灵活性。 2. 单例模式:单例模式确保一个类只有一个实例,并提供一个...

    Java_在终极设计模式包中掌握经典设计模式和实际示例.zip

    其次,工厂模式(Factory Pattern)是创建型设计模式,它提供了一种创建对象的最佳方式,通过一个公共接口来创建特定类型的对象,避免了硬编码类名。工厂方法模式和抽象工厂模式则进一步扩展了这一思想,分别处理类...

    《设计模式》中文版.rar

    职责链模式(Chain of Responsibility)避免硬编码的接收者和发送者;命令模式(Command)将请求封装为一个对象,以便使用不同的请求、队列请求或记录请求;解释器模式(Interpreter)用于定义语言的文法;迭代器...

    java设计模式实例

    9. **责任链模式(Chain of Responsibility)**:避免将处理逻辑硬编码到对象中,而是让对象组成一条链,请求沿着链传递,直到被某个对象处理。 10. **命令模式(Command)**:将请求封装为一个对象,以便使用不同...

    侯捷:设计模式讲义(PDF高清).rar

    结构型模式如适配器模式、桥接模式、装饰器模式等,关注如何组合和连接类与对象,以实现更复杂的功能。行为型模式如策略模式、观察者模式、责任链模式等,关注对象之间的交互和职责分配,使代码更加可扩展和易于维护...

    C#设计模式 及代码

    9. 责任链模式(Chain of Responsibility):避免将处理请求的对象硬编码为调用者,而是让调用者将请求传递给链上的下一个对象。 在“C#设计模式随书源码”和“C#设计模式”这两个文件中,你可以找到上述模式的C#...

    JAVA设计模式.影印版

    它是一种结构型设计模式,能将抽象化与实现细节分离,使二者可以独立进行变化。 ### 组合模式 组合模式将对象组合成树形结构以表示“部分-整体”的层次结构。它能使客户以一致的方式处理单个对象以及对象组合。 #...

    Java设计模式(疯狂Java联盟版)

    还有可能是状态模式(State)和职责链模式(Chain of Responsibility),前者通过改变对象内部状态来改变其行为,后者通过链式结构处理请求,避免硬编码特定的接收者。 设计模式的学习不仅仅是理解每个模式的定义,...

    java设计模式的理解

    工厂模式提供了一种创建对象的最佳方式,避免了硬编码类名和new操作。抽象工厂模式进一步扩展,允许创建一系列相关的对象。 装饰器模式允许在运行时动态地给对象添加新的行为或责任,而不需要修改原有代码。这在...

    swift-使用OC实现常用的23种设计模式

    17. 责任链模式(Chain of Responsibility):避免将处理逻辑硬编码在对象中,而是让对象组成一条链,请求在这条链上传递,直到被某对象处理。 18. 解释器模式(Interpreter):给定一种语言,定义其文法的一种表示...

    C#23设计模式.pdf

    《C# 23种设计模式》是一本深入探讨C#编程中常见设计模式的书籍。设计模式是软件工程中的重要概念,它们是解决特定问题的成熟、可重用的解决方案,代表了在软件设计中经过时间考验的最佳实践。通过理解和应用设计...

    设计模式专题,共 23 种设计模式。GOF design patter-java-design-patterns.zip

    15. **责任链模式(Chain of Responsibility)**:避免将处理逻辑硬编码在对象中,而是让对象形成一个链,依次处理请求。 16. **解释器模式(Interpreter)**:给定一种语言,定义其文法表示,并提供一个解释器,...

    JAVA设计模式.影印版pdf

    避免硬编码接收者和发送者之间的关联。 13. **命令模式**:将请求封装为一个对象,以便使用不同的请求、队列请求,或者支持可撤销的操作。 14. **解释器模式**:给定一个语言,构造一个解释器来处理这种语言。 15...

    JAVA设计模式java 各种设计模式

    15. **责任链模式(Chain of Responsibility)**:避免将处理逻辑硬编码在发送者和接收者之间。发送者只需将请求发送给链中的下一个对象,而接收者则自行决定是否处理该请求。 16. **解释器模式(Interpreter)**:...

Global site tag (gtag.js) - Google Analytics