Java设计模式之装饰者模式

装饰者模式
装饰者模式:动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。
具体被装饰者和抽象装饰类都继承于相同的抽象类,继承的是类型,而不是行为 。行为来自装饰者和基础组件,或与其他装饰者之间的组合关系。它也称为追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;
//综合咖啡
public class 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;

//摩卡装饰者
public class 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
public double cost() {
// TODO Auto-generated method stub
return 0.2+beverage.cost();
}
}
测试类:
package com.whut.decorate;

public class CustomerDrink {

public static void 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)装饰者会导致设计中出现许多小对象,如果过度使用,会让程序变得很复杂。


你可能感兴趣的:(java,设计,装饰者模式)