`
zhongguo168a
  • 浏览: 45639 次
  • 性别: Icon_minigender_1
  • 来自: 珠海
社区版块
存档分类
最新评论

【AS3与设计模式】 Decorator Pattern (装饰者模式)

阅读更多

 

2007-09-05 14:07:42 | 发布: N神

 

[arrow] 关于这一系列的索引页和说明请点这里 http://www.nshen.net/blog/article.asp?id=510

[arrow] 直接下Decorator Pattern演示代码的点这里

先看一下定义:

The Decorator Pattern attaches additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality 。

大概意思就是说

装饰者模式可以动态地给一个对象增加其他职责。装饰者模式提供一个比继承更灵活方法扩展对象的功能。

什 么是动态和静态呢? 简单的说,就是静态对应继承,比如现在有一个类,现在想给其增加一些方法,静态的办法就是写一个类 extends 原来的类,在其中扩展一些方法,而动态对应组合 同样的问题动态的办法就是在runtime时运用组合给类增加方法。随便找本oo的书肯定有写组合比继承灵活,翻出来看看吧。

看一下怎么动态增加职责的:


//比如原来有一个类起名叫ConcreteComponent
 var concreteComponent:ConcreteComponent=new ConcreteComponent();

//ConcreteComponent有一个operation的方法,只是简单的trace
 concreteComponent.operation() //trace: 原始行为

 //下面开始扩展原始的行为了,声明一个新装饰器叫做ConcreteDecoratorA ,把原来的concreteComponent给装饰一下~
 var concreteDecoratorA:ConcreteDecoratorA= new ConcreteDecoratorA(concreteComponent)

 //现在再调用operation方法吧(扩展了装饰之前的operation方法)
 concreteDecoratorA.operation()
 //trace: 原始行为 经过ConcreteDecoratorA装饰!

 //下面再重新装饰一个新行为
 var concreteDecoratorB:ConcreteDecoratorB=new ConcreteDecoratorB(concreteComponent)
 //这回经过装饰后,出现了新的方法叫newOperation
 concreteDecoratorB.newOperation()
 //trace: 被装饰的新行为 newOperation()方法


该看看具体是怎么实现的了

类图到现在我还不会画,不过谷哥就是强,随便一搜就找到类图了



附加一个《head first design pattern》 里的图



Decorator跟Component之间的关系解释

引用
Decorator 是装饰者模式里非常特殊的一个类,它既继承于Component【IS A关系】,又维护一个指向Component实例的引用【HAS A关系】,换个角度来说,Decorator跟Component之间,既有动态组合关系又有静态继承关系,WHY? 这里为什么要这么来设计?上面我们说过,组合的好处是可以在运行时给对象增加职责,Decorator【HAS A】Component的目的是让ConcreteDecorator可以在运行时动态给ConcreteComponent增加职责,这一点相对来说还 比较好理解;那么Decorator继承于Component的目的是什么?在这里,继承的目的只有一个,那就是可以统一装饰者和被装饰者的接口,换个角 度来说,不管是ConcretComponent还是ConcreteDecorator,它们都是 Component,用户代码可以把它们统一看作Component来处理,这样带来的更深一层的好处就是,装饰者对象对被装饰者对象的功能职责扩展对用 户代码来说是完全透明的,因为用户代码引用的都是Component,所以就不会因为被装饰者对象在被装饰后,引用它的用户代码发生错误,实际上不会有任 何影响,因为装饰前后,用户代码引用的都是Component类型的对象,这真是太完美了!装饰者模式通过继承实现统一了装饰者和被装饰者的接口,通过组 合获得了在运行时动态扩展被装饰者对象的能力。

//上边这段话转自某文章,地址找不到了抱歉 [sad]

各个部分:

Component(被装饰对象基类) 一个抽象类或接口

package net.nshen.designpatterns.decorator
{
  public class Component
  {
    public function operation():void{  
    }
  }
}


ConcreteComponent(具体被装饰对象) 定义具体的对象,Decorator可以给它增加额外的职责;

package net.nshen.designpatterns.decorator
{
  //被装饰者
  public class ConcreteComponent extends Component
  {
    override public function operation():void{
     trace("原始行为")
    }
  }
}


Decorator(装饰者抽象类) 维护一个指向Component实例的引用(这个实例就是要被装饰的对象),并且定义了与Component一致的接口;

package net.nshen.designpatterns.decorator
{
  public class Decorator extends Component
  {
    //被装饰者
    private var _component:Component
    
    public function Decorator(p_component:Component):void{
     this._component=p_component;
    }
    
    override public function operation():void{
     this._component.operation()
    }
  }
}


ConcreteDecorator(具体装饰者) 具体的装饰对象,给内部持有的具体被装饰对象增加具体的职责

扩展现有的方法

package net.nshen.designpatterns.decorator
{
  public class ConcreteDecoratorA extends Decorator
  {
    public function ConcreteDecoratorA(p_component:Component)
    {
      super(p_component);
    }
     override public function operation():void{
     super.operation()
     trace("经过ConcreteDecoratorA装饰!")
    }
  }
}


增加新方法

package net.nshen.designpatterns.decorator
{
  public class ConcreteDecoratorB extends Decorator
  {
    public function ConcreteDecoratorB(p_component:Component)
    {
      super(p_component);
    }
    //装饰新行为
    public function newOperation():void{
     trace("被装饰的新行为 newOperation()方法")
    }
    
  }
}


最后看一下目前为止的测试类designpattern.as吧

package {
  import flash.display.Sprite;
 import net.nshen.designpatterns.strategy.*;
 import net.nshen.designpatterns.decorator.*;
 import net.nshen.designpatterns.singleton.Singleton;
 
 
  public class designpatterns extends Sprite
  {
    public function designpatterns()
    {
      //Test_Strategy()
      //Test_Singleton()

      Test_Decorator()
    }
    
    
    public function Test_Strategy():void{
     var context:Context=new Context();
     //设置策略
     context.strategy=new ConcreteStrategyA()
     context.ContextInterface()
     //runtime 更改策略B
     context.strategy=new ConcreteStrategyB()
     context.ContextInterface()
     //runtime 更改策略C
     context.strategy=new ConcreteStrategyC()
     context.ContextInterface()
    }
    
    public function Test_Decorator():void{
     var concreteComponent:ConcreteComponent=new ConcreteComponent();
     concreteComponent.operation()
     //扩展原始的行为
     var concreteDecoratorA:ConcreteDecoratorA= new ConcreteDecoratorA(concreteComponent)
     concreteDecoratorA.operation()
     //装饰新行为
     var concreteDecoratorB:ConcreteDecoratorB=new ConcreteDecoratorB(concreteComponent)
     concreteDecoratorB.newOperation()
    }
    
    public function Test_Singleton():void{
     var s:Singleton=Singleton.getInstance()
     s.doSomething();
     /*
     使用构造函数创建实例会报错
     var s1:Singleton=new Singleton()
     s1.doSomething()
     */
    }
    
    
  }
}


[arrow] 完整代码下载点这里

=================理论与实践分割线=========================================================

实践1:实现 IEventDispatcher 接口来进行事件发送。

这个例子我是在kingda的blog上发现了的,感谢一下他,原文地址
http://www.kingda.org/archives/kingda/2006/08/as30106.html

以下是原文末端部分节选的

引用
类可能是因为本身已经继承了其它类,无法再继承EventDispatcher。
而我们恰恰希望它能实现EventDispatcher类所有功能,比如说addEventListener, hasListener等等,看起来简直和继承EventDispatcher没什么分别。
那么OK,我建议使用 实现IEventDispatcher接口来进行事件发送。
其实质是一个装饰器模式(Decorator),以对客户端透明的方式扩展对象功能,是继承关系的一个替代方案。其关键在于扩展是完全透明的,使用起来和继承父类几乎没什么区别。

具体方法
由于IEventDispatcher需要实现5个接口,addEventListener, hasListener, willTrigger,removeEventListener,hasEventListener,那么我们的装饰类也必须实现这五个接口。
其余看代码

优点:
1.类的用户完全感觉不到差别
2.在被包装的方法中还可以加入其它自己希望加进去的动作,比如,在addEventListenr方法中可以再插入一个计数,看看到底被add了多少次,超过某些次后,调用某个方法等等。
总而言之,给我们带来了极大的灵活性。这就是装饰器模式的好处。
package {
 import flash.display.Sprite;
 import flash.events.Event;
 import flash.events.MouseEvent;
 import flash.events.EventDispatcher;
 
 public class LearnDecoratorEvents extends Sprite {
    public function LearnDecoratorEvents() {
      
      var kingdaObj:KingdaClass = new KingdaClass();
      kingdaObj.addEventListener(KingdaClass.ACTION, lisFunc); //用起来和EventDispatcher对象一样哦,呵呵。
      
      var evtObj:Event = new Event(KingdaClass.ACTION);
      kingdaObj.dispatchEvent(evtObj);//确实一样吧 :)
      //输出:listened:yeahyeah
    }
    
    private function lisFunc(evtObj:Event):void {
      trace ("listened:"+evtObj.type);
    }
  }
  import flash.events.IEventDispatcher;
  import flash.events.EventDispatcher;
  import flash.events.Event;

  class KingdaClass implements IEventDispatcher{
    public var _dispatcher:EventDispatcher;
    public static const ACTION:String = "yeahyeah";
    
    public function KingdaClass() {
      // other ....
      initSender();
    }
    
    private function initSender():void {
      _dispatcher = new EventDispatcher(this);
    }
 //哈哈,在实现接口时还可以乘机干点别的,比如我喜欢吧useWeakReference设为true
   public function addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = true):void{
   // do other things;
   _dispatcher.addEventListener(type, listener, useCapture, priority, useWeakReference);
    }
 
   public function dispatchEvent(evt:Event):Boolean{
   // do other things;
      return _dispatcher.dispatchEvent(evt);
   }
 
   public function hasEventListener(type:String):Boolean{
      // do other things;
 return _dispatcher.hasEventListener(type);
   }
 
   public function removeEventListener(type:String, listener:Function, useCapture:Boolean = false):void{
   // do other things;
    _dispatcher.removeEventListener(type, listener, useCapture);
   }
 
   public function willTrigger(type:String):Boolean {
   // do other things;
    return _dispatcher.willTrigger(type);
   }
  }
}


实践2 :
听iiley说aswing里的Border是用Decorator设计的,有兴趣的可以看看,俺aswing没细学过,Border是做什么的都不知道,以后再研究
,仍然是有例子的跟我联系,或者留言,谢谢了

分享到:
评论

相关推荐

    设计模式之装饰模式(Decorator Pattern)

    装饰模式(Decorator Pattern)是一种结构型设计模式,它在不改变原有对象的基础上,通过包裹一个对象并为其添加新的行为或责任,实现对对象功能的扩展。这种模式在软件开发中非常常见,尤其当需要在运行时动态改变...

    C#设计模式之Decorator 装饰模式

    装饰模式(Decorator Pattern)是设计模式中的一种结构型模式,它在不改变原有对象的基础上,通过添加额外的职责来扩展对象的功能。在C#中,装饰模式尤其适用于那些需要动态地增加或减少对象功能的情况,避免了使用...

    Head First 设计模式 (三) 装饰者模式(decorator pattern) C++实现

    装饰者模式(Decorator Pattern)是一种结构型设计模式,它允许我们向对象添加新的行为或职责,而无需修改对象的原始代码。在C++中实现装饰者模式,可以让我们灵活地扩展对象的功能,同时保持代码的可读性和可维护性...

    装饰者模式(Decorator Pattern)原理图

    装饰者模式(Decorator Pattern)是一种结构型设计模式,它的定义是在不改变原有对象结构的基础上,动态地给该对象增加一些职责(即增加其额外功能)。这种模式允许向一个现有的对象添加新的功能,同时又不改变其...

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

    3. **装饰者(Decorator)**:持有一个组件对象的引用,并且定义与组件接口一致的方法。装饰者可以在调用组件方法前后添加额外的行为。 4. **具体装饰者(Concrete Decorator)**:实现了装饰者接口,负责给组件...

    [结构型模式] head first 设计模式之装饰者模式(decorator)

    装饰者模式(Decorator Pattern)是结构型设计模式之一,它允许在运行时向对象添加新的行为或职责,而无需修改对象的源代码。这个模式的名字来源于装饰艺术,它通过添加额外的装饰来增强一个物体的外观,同样地,...

    c++-设计模式之装饰模式(Decorator)

    装饰模式(Decorator Pattern)是一种结构型设计模式,允许在不改变对象接口的情况下,动态地为对象添加额外的职责或功能。装饰模式通常用于需要扩展对象功能而又不希望使用子类化的场景。 装饰模式的组成 组件接口...

    AS3设计模式

    装饰器模式(Decorator)动态地给对象添加额外的责任,而桥接模式(Bridge)将抽象部分与实现部分分离,使它们可以独立变化。 3. **行为型模式**:这些模式定义了对象之间的职责分配,如观察者模式(Observer),在...

    装饰者模式——Decorator

    装饰者模式(Decorator)是一种设计模式,用于在运行时动态地给对象添加额外的责任或功能。它是结构型设计模式的一种,能将行为的增加与对象的创建分离,使得我们可以独立地扩展对象的功能。 在Java或其他面向对象...

    DecoratorPattern.rar

    装饰器模式(Decorator Pattern)是一种设计模式,它允许在运行时动态地给对象添加新的行为或职责,而无需改变对象本身。在Java开发中,这种模式尤其有用,因为它提供了扩展对象功能的方式,同时保持了代码的灵活性...

    Java24种设计模式,Java24种设计模式,24种设计模式,学会了这24种设计模式,可以打遍天下无敌手,设计模式非常重要

    13、装饰模式DECORATOR PATTERN 14、迭代器模式ITERATOR PATTERN 15、组合模式COMPOSITE PATTERN 16、观察者模式OBSERVER PATTERN 17、责任链模式 18、访问者模式VISITOR PATTERN 19、状态模式 20、原型模式 21...

    设计模式 t07Decorator

    在给定的“设计模式 t07Decorator”主题中,我们聚焦于装饰者模式(Decorator Pattern)。装饰者模式是一种结构型设计模式,它允许我们在运行时给对象添加新的行为或职责,而无需修改其原有代码。这种模式遵循开闭...

    设计模式之 Decorator模式和代码实现

    【Decorator模式】是一种设计模式,它允许在运行时动态地给对象...在实际的软件开发中,Decorator模式同样适用于那些需要动态增减功能的对象,例如在UI设计中添加装饰元素,或者在数据库连接池中添加不同的连接策略等。

    PHP设计模式(八)装饰器模式Decorator实例详解【结构型】

    装饰器模式(Decorator Pattern)是一种结构型设计模式,主要用于在运行时动态地给对象添加新的职责或行为,而不必改变现有对象的类定义。在面向对象编程中,装饰器模式提供了一种相对于继承更加灵活的方式来增强或...

    Java设计模式之-Decorator装饰模式

    3. Decorator(装饰者):维护一个指向Component对象的引用,并且也实现了Component接口,这样 Decorator 可以代替 Component 被使用。 4. ConcreteDecorator(具体装饰者):为Component对象添加新的行为或属性,...

    java Decorator装饰模式例子

    装饰模式(Decorator Pattern)是设计模式中的一种结构型模式,它允许在运行时给对象添加新的行为或职责,而无需改变对象的类。在Java中,装饰模式通常通过继承和组合来实现,使得代码具有更好的扩展性和灵活性。...

    设计模式C++学习之装饰模式(Decorator)

    装饰模式(Decorator)是软件设计领域中一种非常实用的结构型设计模式,它允许我们向一个对象添加新的行为或责任,而无需修改该对象的源代码。在C++编程语言中,装饰模式常用于动态地扩展类的功能,使得类的行为在...

Global site tag (gtag.js) - Google Analytics