Decorator 装饰模式

本文介绍Decorator装饰模式,一种允许在不改变对象接口的前提下为其添加新功能的设计模式。通过实例演示了如何利用装饰模式为基本形状类添加拖拽及颜色变化等功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Decorator 装饰模式,对象结构模式,动态的给对象添加额外的职责。就增加功能而言,Decorator 比生成子类更为灵活。

 

Decorator 又叫wrapper,相当于在原来的物体上面又套了个东西,但是不改变原来的接口。它是对某个对象添加一些功能而不是整个类。比如一个文本套了个边框接口没变,然后又套了个滚动条,接口还是没有变。

 

 

Decorator 在actionscript设计模式有讲,他比静态的继承更为灵活、与它的compont不一样,是一个透明的包装可以很容易的添加一个特性。但是,采用Decotor会产生很多的类似的小对象,导致学习它很难,也很难排错。

 

使用Decorator要注意,接口的一致性,当你只要添加一个职责时,没有必要定义抽象Decorator类,保持装饰对象的简单性。当componen本身就很庞大时,使用Decorator的代价是很高的,strategy会好点。

 

 

 


 


 

 

 

装饰器模式采用的是组合而不是继承来给对象添加新的行为。

 

 

参与者:

Component,定义一对象的接口,可以给这个对象动态的添加职责。

ConcreteComponent,定义一对象,可以给这个对象动态的添加职责。

Decorator,维持一个指向Compoennt的对象引用,并定义一个和Components一致的接口。

ConcreteDecorator,向组件添加行为。

 

注意,Decorator是要和被装饰的对象有一致的接口的,和Proxy一样,而Adaptor是个接口转换器,两个接口并没有直接的联系。Composite也是一致的接口,他是强调单个和群体,有一致的接口。

 

 

下面来举个例子说明下,Decorator是怎么用的:

 

 


 

 

AdstractBasicShap .as

package {
    import flash.display.*;
    
    public class AdstractBasicShap extends Sprite {
        public function AdstractBasicShap() {
        
        }
    }
}
 

 

Cicle .as

package {
    import flash.display.*;
    
    public class Cicle extends AdstractBasicShap {
        public function Cicle(radius:Number) {
            graphics.lineStyle(2,0,1);
            graphics.beginFill(0xFFFFFF,0.3);
            graphics.drawCircle(radius,radius,radius);
            graphics.endFill();
        }
    }
}
 

 

Rectangle.as

package {
    import flash.display.*;
    
    public class Rectangle extends AdstractBasicShap {
        public function Rectangle(ShapeWidth:Number,
                        shapHeight:Number,
                        center:Boolean = false) {
			
            graphics.lineStyle(2,0,1);
            graphics.beginFill(0xFFFFFF,0.3);
            graphics.drawRect(center? - ShapeWidth/2:0,center?-shapHeight/2:0,ShapeWidth,shapHeight);
            graphics.endFill();
        }
    }
}
 

 

DraggableSahpe .as

package {
    import flash.display.*;
    import flash.events.*;
	
    public class DraggableSahpe extends AdstractBasicShap {
        private var decorated:AdstractBasicShap;
        public function DraggableSahpe(decorated:AdstractBasicShap) {
            addChild(decorated);
            
            addEventListener(MouseEvent.MOUSE_DOWN,onMouseDownHandler);
            addEventListener(MouseEvent.MOUSE_UP,onMouseUpHandler);
        }
        
        
        private function onMouseDownHandler(e:MouseEvent):void {
            startDrag();
        }
        
        private function onMouseUpHandler(e:MouseEvent):void {
            stopDrag();
        }
        
    }
}
 

 

 

ColorableShape .as

package {
	import flash.geom.*;
    public class ColorableShape extends AdstractBasicShap {
        public function ColorableShape(shape:AdstractBasicShap,
                    red:uint,green:uint,blue:uint) {
            shape.transform.colorTransform = new ColorTransform(red,green,blue);
            addChild(shape);
        }
    }
}
 

 

ResizeableShape .as

package {
	import flash.events.*;
    public class ResizeableShape extends AdstractBasicShap {
        private var decorated:AdstractBasicShap;
        private var isResizing:Boolean;
        private var resizer:AdstractBasicShap;
        
        override public function set width(value:Number):void {
            decorated.width = value;
            resizer.x = value;
        }
        
        override public function set height(value:Number):void {
            decorated.height = value;
            resizer.y = value;
        }
        
        public function ResizeableShape(shape:AdstractBasicShap) {
            decorated = shape;
            addChild(decorated);
            
            resizer = new Rectangle(10,10,true);
            resizer = new ColorableShape(resizer,0.8,0.8,0.8);
            resizer.x = decorated.width;
            resizer.y = decorated.height;
            addChild(resizer);
            
            resizer.addEventListener(MouseEvent.MOUSE_DOWN,onMouseDownHandler);
            resizer.addEventListener(MouseEvent.MOUSE_UP,onMouseUpHandler);
			
        }
        
        private function onMouseDownHandler(e:MouseEvent):void {
			addEventListener(Event.ENTER_FRAME,onEnterframeHandler);
			
            resizer.startDrag(true);
            e.stopImmediatePropagation();
        }
        
        private function onMouseUpHandler(e:MouseEvent):void {
            resizer.stopDrag();
            removeEventListener(Event.ENTER_FRAME,onEnterframeHandler);
        }
        
        private function onEnterframeHandler(e:Event):void {
            if(resizer.x < 0) {
                resizer.x = 0;
            }
            
            if(resizer.y < 0) {
                resizer.y = 0;
            }
            
            decorated.width = resizer.x;
            decorated.height = resizer.y;
        }
    }
}
 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值