您的位置:首页 > 编程语言 > Java开发

Java设计模式之装饰者模式

2013-03-16 09:13 447 查看
装饰者模式 装饰者模式:动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。 具体被装饰者和抽象装饰类都继承于相同的抽象类,继承的是类型,而不是行为。行为来自装饰者和基础组件,或与其他装饰者之间的组合关系。它也称为追MM模式。 在实际开发中,对于应用中,如果一个基类包含许多个不同的子类,而每一个子类具有不同的附加物。此时就可以考虑用装饰者模式了。在装饰者模式中,要划分出哪些是主体部分,哪些是装饰者。而一个主体可以拥有多个装饰者,装饰者又可以继续装饰装饰者,则就需要主体和装饰者继承于一个相同的基类类型。这样通过继承后,继承的就是类型,而不是行为。每一个装饰者都“有一个”主体,装饰者内部有一个实例变量作为引用保存某一个主体的。所有的装饰者统一实现一个装饰者接口。 通常在装饰者模式中,都采用抽象类。装饰者模式,被装饰者必须和装饰者实现相同的接口,一般是在装饰者行为或方法中转发给被装饰者行为(即调用被装饰者的行为)。 在开发过程中,如果过于依赖继承,则类的行为就会在编译的时候静态决定了,行为如果不是来自超类,就是来自子类覆盖后的版本。而如果利用组合,在可以在运行中动态的组装了。具体事例: 一个酒店有多个饮料,但是所有的饮料都需要继承同一个类,而每个饮料却又有不同的添加物. 抽象基类:package com.whut.decorate;
//装饰者模式
public abstract class Beverage {

String description="Unknown Beverage";

public String getDescription()
{
return description;
}

public abstract double cost();
} 它有多个具体类型的饮料,也就是多个被装饰者。列举一个:package com.whut.decorate;
//综合咖啡
publicclass HouseBlend extends Beverage {

public HouseBlend()
{
description="HouseBlend";
}

@Override
public double cost() {
// TODO Auto-generated method stub
return 0.89;
}
}
由于每一个被装饰者,即饮料均有多个不同的添加。装饰者的抽象类类如下:package com.whut.decorate;

//装饰者基类
public abstract class CondimentDecorator extends Beverage {
public abstract String getDescription();
} 具体装饰者:package com.whut.decorate;

//摩卡装饰者
publicclass Mocha extends CondimentDecorator {
Beverage beverage;
public Mocha(Beverage beverage)
{
this.beverage=beverage;
}

@Override
public String getDescription() {
// TODO Auto-generated method stub
return beverage.getDescription()+",Mocha";
}

@Override
publicdouble cost() {
// TODO Auto-generated method stub
return 0.2+beverage.cost();
}
}
测试类:package com.whut.decorate;

publicclass CustomerDrink {

publicstaticvoid main(String[] args)
{
Beverage beverage=new Espresso();
System.out.println(beverage.getDescription()+" $"+beverage.cost());

//注意这种方式
//顶了两个Mocha和Whip的DarkRoast咖啡
Beverage beverage2=new DarkRoast();
beverage2=new Mocha(beverage2);
beverage2=new Mocha(beverage2);
beverage2=new Whip(beverage2);
System.out.println(beverage2.getDescription()+" $"+beverage2.cost());

Beverage beverage3=new HouseBlend();
beverage3=new Soy(beverage3);
beverage3=new Mocha(beverage3);
beverage3=new Whip(beverage3);
System.out.println(beverage3.getDescription()+" $"+beverage3.cost());

}
}
这里就是在运行中动态的装饰饮料。在java中,常见的装饰者模式,就是I/O类。设计原则:类应该对扩展开放,对修改关闭。主要的意思就是允许类容易扩展,在不修改现有的代码情况下,可以搭配新的行为,而这些行为往往是在运行的时候搭配的,通过装饰者模式动态的将责任附加到对象中。要点总结1)继承属于扩展形式之一,但不见得是达到弹性设计的最佳方式。2)在设计中,应该允许行为可以被扩展,而无须修改现有的代码。3)组合和委托可用于在运行时动态地加上新的行为。4)除了继承,装饰者模式也可以让我们扩展行为。5)装饰者模式意味着一群装饰者类,这些类用来包装具体组件。6)装饰者类反映出被装饰的组件类型(事实上,他们具有相同的类型,都经过接口或继承实现)。7)装饰者可以在被装饰者的行为前面与/或后面加上自己的行为,甚至将被装饰者的行为整个取代掉,而达到特定的目的。8)可以用无数个装饰者包装一个组件。9)装饰者一般对组件的客户是透明的,除非客户程序依赖于组件的具体类型。10)装饰者会导致设计中出现许多小对象,如果过度使用,会让程序变得很复杂。

本文出自 “在云端的追梦” 博客,请务必保留此出处http://computerdragon.blog.51cto.com/6235984/1155600
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: