第八讲装饰(Decorator)模式场景Mary过完轮到Sarly过生日,还是不要叫她自己挑了,不然这个月伙食费肯定玩完,拿出我去年在华山顶上照的照片,在背面写上“最好的礼物,就是爱你的Fita”,再到街上礼品店买了个像框,再找隔壁搞美术设计的Mike设计了一个漂亮的盒子装起来......,我们都是Decorator,最终都在修饰我这个人呀装饰模式概述装饰模式是动态地扩展一个对象的功能,而不需要改变原始类代码的一种成熟模式。装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案,提供比继承更多的灵活性。动态给一个对象增加功能,这些功能可以再动态的撤消。装饰模式概述使用装饰模式扩展功能不会产生类爆炸。它采用的是合成方式,比继承方式更加灵活。装饰模式要解决的问题:提供一种修改类的行为,而避免创建众多的派生类的途径。适用性=以下情况使用装饰模式:→在不影响其他对象的情况下,给单个对象动态添加职责。→当不能采用生成子类的方法进行扩展时。有时可能有大量独立的扩展,将产生子类的爆炸性增长以支持每种组合。或者类定义可能被隐藏或不能用于生成子类。装饰模式的角色抽象组件(Component)具体组件(ConcreteComponent)装饰(Decorator)具体装饰(ConcreteDecotator)装饰模式的UML类图装饰模式示例1.抽象组件:Bird.javapublicabstractclassBird{publicabstractintfly();}装饰模式示例2.具体组件:Sparrow.javapublicclassSparrowextendsBird{publicfinalintDISTANCE=100;publicintfly(){returnDISTANCE;}}装饰模式示例3.装饰(Decorator):Decorator.javapublicabstractclassDecoratorextendsBird{protectedBirdbird;publicDecorator(){}publicDecorator(Birdbird){this.bird=bird;}}装饰模式示例4.具体装饰(ConcreteDecotator):SparrowDecorator.javapublicclassSparrowDecoratorextendsDecorator{publicfinalintDISTANCE=50;//eleFly方法能飞50米SparrowDecorator(Birdbird){super(bird);}publicintfly(){intdistance=0;distance=bird.fly()+eleFly();returndistance;}privateinteleFly(){//装饰者新添加的方法returnDISTANCE;}}装饰模式示例5.应用Application.javapublicclassApplication{publicvoidneedBird(Birdbird){intflyDistance=bird.fly();System.out.println(这只鸟能飞行+flyDistance+米);}publicstaticvoidmain(Stringargs[]){Applicationclient=newApplication();Birdsparrow=newSparrow();BirdsparrowDecorator1=newSparrowDecorator(sparrow);BirdsparrowDecorator2=newSparrowDecorator(sparrowDecorator1);client.needBird(sparrowDecorator1);client.needBird(sparrowDecorator2);}}使用装饰模式的要点装饰者与被装饰者具有相同的类型可以用多个装饰者装饰一个对象由于装饰者与被装饰者具有相同的类型,我们可以用装饰后的对象代替原来的对象对象可以在任何时候被装饰,因此我们能在运行时动态的装饰对象。装饰者在委派它装饰的对象作某种处理时,可以添加上自己的行为(功能扩展)(在委派之前或/和之后)。使用装饰模式的要点所谓委派就是一个对象将工作(或工作的一步分)交给另一个对象来完成。在装饰模式中,委派是指装饰对象将任务交给被装饰对象来完成。委派可以传递,最终必须要有一个干实事的对象。思考题试分析本课开头的场景里每个人分别对应的装饰模式的角色