您的位置:首页 > 其它

【设计模式】装饰者模式-明月装饰了你的窗子

2017-09-03 17:29 260 查看

装饰者模式

  使用装饰者模式,可以动态的给一个对象添加一些额外的职责。这适用于,我们只希望给某个对象而不是整个类添加一些功能的场景。通过使用含有某个特定功能的类来“包裹”原始的类,提供给原始的类某些它本身不具备的特性。比如,我们有一杯“茉莉茶”,现在加上一颗“柠檬”,那我们就有了一杯“柠檬茉莉花茶”。“柠檬”作为一个装饰者,提供了“茉莉茶”本身没有的清爽口感。当然,这也带来了一定的负担,你需要花更多的“钱”。

 

1. 定义

  装饰者模式动态地将职责附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的解决方案。

 

2. 为什么需要

  装饰者提供了继承更高的灵活性。可以使用继承来实现将父类的功能添加到子类中,但是这种方式限制了用户选择的权利,没有办法选择将父类的哪些功能添加到子类中,只能被动的接受父类所有的功能。作为一个类而言,拥有更多的功能并不一定是件好事。所有的类都不应该试图成为一个“全栈“。装饰者模式则刚好提供了用户选择的权利,用户可以”谨小慎微“的选择自己需要的功能,而不用为自己不需要的功能去买单。

  该模式的实现方式,也被它的名字清楚的表达。

  装饰。

 

3. 实现方案

   3.1 实现注意点

接口一致性。装饰对象的接口必须与它所装饰的类的接口是一致的。体现了“装饰”过程不能改变对象的“本质”

省略抽象的装饰者类。
改变对象的外壳。装饰者Decorator可以被看做是一个对象的外壳,它可以改变对象的行为。

  3.2 实现代码

  参与者:

一个 抽象类Tea ,用于表示茶的最顶层类。
一个具体类 JasmineTea ,表示茶的一种,茉莉茶。
一个抽象类 TeaDecorator  ,表示茶的装饰者。用于向茶中加入不同的配料。
一个具体类 Lemon ,继承 TeaDecorator ,表示可以向茶中加入的配料,柠檬。

 

  抽象类 Tea 实现代码如下:

/*
为一个抽象类,所有的茶都需要直接或间接的继承它
*/
public abstract class Tea {

private String description = "tea";

public String getDescription() {
return description;
}
}


  

  具体类 JasmineTea 实现代码如下:

/**
* 现在小店只提供一种茶,茉莉茶。
*
* 可以向它添加不同的茶调料,搭配不同的口味
*/
public class JasmineTea extends Tea {

@Override
public String getDescription() {
return "jasmine tea";
}
}


  小店刚开业,只提供茉莉花茶,请多担待。不过,我们提供了配料可以搭配不同的口味。

  先需要提供一个 TeaDecorator 的抽象类,它可以提供不同的配料,实现代码如下:

/*
茶的装饰者,比如凉茶,柠檬茶等
*/
public abstract class TeaDecorator extends Tea{

public abstract String getDescription();
}


  接下来,则是本店现今提供的唯一调料,柠檬,实现代码如下:

/*
这是一个“茶”的装饰者,表示在茶中加入柠檬
*/
public class Lemon extends TeaDecorator {

private Tea tea;

/**
* 注意:这里需要传入“一杯茶”,也就是要“被装饰”的对象
* 这里的语义:有一杯茶,需要向茶中加入柠檬。
* 理所当然的,柠檬就是一个“装饰者”
*/
public Lemon(Tea tea) {
this.tea = tea;
}

public String getDescription() {
return "lemon " + tea.getDescription();
}
}


  好!小店已经准备好了茶,也准备好了调料。那是时候给各位客观端上一杯沁人心脾的“柠檬茉莉花茶”了,代码实现如下:

public class App {

public static void main(String[] args) {

Tea jasmineTea = new JasmineTea(); // 先冲一杯清香的茉莉茶
Tea lemonJasmineTea = new Lemon(jasmineTea); // 然后向茶中加入一颗柠檬

System.out.println(lemonJasmineTea.getDescription()); // 一杯生津止渴的 “lemon jasmine tea” 就泡好了
}
}


  端上一杯“柠檬茉莉花茶”,就着网易云音乐,看着“四人帮”的设计模式,岂不美哉!

4. 总结  

  装饰者的主要特点在于在不影响其他对象的情况下,可以动态的给单个对象添加职责。关于这点,我们可以参考JDK中的 java.io 包,它是使用装饰者模式的典型场景。装饰者模式有如下优点:

相比静态继承提供了更大的灵活性。它可以在运行时增加和删除职责。此外,可以很容易的重复添加一个特性。
避免了在层次结构高层的类有太多的特性。它不在一个类中支持所有的特性,每个装饰者类可以只有一个特性。可以从简单的部件复合出复杂的功能。

  使用该模式也会引入一些问题:

有许多小的对象。过多的对象会使得有些人反感,反正我个人还是挺喜欢小的函数、类、模块...
 

  装饰的内涵在于不改变原有本质的前提下提供原来没有的功能。我们需要区分哪些是需要被装饰的,而哪些是装饰者。更多的时候是,我们装饰着别人,同时又被别人所装饰。

 

  正所谓:明月装饰了你的窗子,你装饰了别人的梦...

  好梦!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: