您的位置:首页 > 其它

设计模式笔记——装饰者模式

2015-10-16 15:03 253 查看
应用场景举例:一碗普通的面条,加上几块红烧牛肉就是红烧牛肉面,再加上点辣椒就是香辣牛肉面,如果换成加老坛酸菜就是老坛酸菜面

(这酸爽)。Java世界中的装饰者是 I/O类,如
<span style="font-size:18px;">InputStream is=new LineInputStream(new FileInputStream("file.txt"));</span>


为什么要使用装饰者:1:防止类爆炸,因为除了上面提到的还有臊子面、油泼面,有微辣、中辣、特辣等等;2:利用组合动态的组建对象,可以写新的代码添加新功能,而无须修改现在代码。

定义:装饰者模式动态地将责任附加到对象上。若要扩展功能,装饰者提供了继承更有弹性的替代方案。

设计原则:类应该对扩展开放,对修改关闭。

应用例子:

一、结构



二、代码

<span style="font-size:18px;">/**
* Created by zfeng on 2015/10/16.
*
* Noodles是一个抽象类,有两个方法getDescription()和cost(),
* getDescription()已经实现,但cost()方法必须在子类中实现。
*/
public abstract class Noodles
{
String description="Normal Noodles";

public String getDescription()
{
return description;
}
public abstract double cost();
}

/**
* Created by zfeng on 2015/10/16.
*
* 首先,必须让CondimentDecorator能够取代Noodles,所以
* CondimentDecorator扩展自Noodles。
*/
public abstract class CondimentDecorator extends Noodles
{
public abstract String getDescription();
}

/**
* Created by zfeng on 2015/10/16.
* 首先,手擀面扩展自Noodles类,因为手擀面是一种面条
*/
public class HandMadeNoodles extends Noodles
{
/**
* 为了要设置饮料的描述,我们写了一个构造器。description继承自Noodles
*/
public HandMadeNoodles()
{
description="HandMadeNoodles";
}

/**
* 计算价格
* @return
*/
@Override
public double cost() {
return 5.2;
}
}

/**
* Created by zfeng on 2015/10/16.
*LoaTan是一个装饰者,所以让它扩展自CondimentDecorator
*/
public class LaoTan extends CondimentDecorator
{
Noodles noodles;

public LaoTan(Noodles noodles)
{
this.noodles=noodles;       //让LaoTan能够引用一个Noodles。
}

/**
* 我们希望不只是描述面(例如:手擀面),而是完整地连调料都描述出来(例如,老坛酸菜手擀面)。
* 所以首先利用委托的做法,得到一个叙述,然后在其后加上附加的叙述。
* @return
*/
@Override
public String getDescription() {
return noodles.getDescription()+", LaoTan";
}

/**
* 计算总共的价格
* @return
*/
@Override
public double cost() {
return 2+noodles.cost();
}
}

public class Chili extends CondimentDecorator
{
Noodles noodles;

public Chili(Noodles noodles)
{
this.noodles=noodles;
}

@Override
public String getDescription() {
return noodles.getDescription()+", Chili";
}

@Override
public double cost() {
return 1+noodles.cost();
}
}

public static void main(String []args)
{
//要一碗手擀面
Noodles noodles = new HandMadeNoodles();
//加老坛酸菜
noodles=new LaoTan(noodles);
//加辣椒
noodles=new Chili(noodles);

//要一碗方便面
Noodles noodles1=new InstantNoodles();
//加辣椒
noodles1=new Chili(noodles1);

System.out.println(noodles.getDescription()+"  ¥"+noodles.cost());
System.out.println(noodles1.getDescription()+"  ¥"+noodles1.cost());
}</span>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: