参照《大话设计模式》这本书以及网上的一些博客,对设计模式有了一些基本的认识。
通俗的理解,就是对已经存在某些类进行装饰,来扩展他的一些的功能。
装饰模式的基本结构是:
Component 为统一接口,也是装饰类和被装饰类的基本类型
ConcreteComponent 为具体的实现类,也是被装饰类,他本身是个具有一些功能的完整的类。
Decorator 是装饰类,实现了Component接口的同时还在内部维护了一个ConcreteComponent的实例,并可以通过构造函数进行初始化。而Decorator本身,通常采用的是默认的实现,他的存在仅仅是一个声明:我要产生出一些用于装饰的子类。而子类才是具有赋有具体装饰效果的装饰产品类。
ConcreteDecorator是具体的装饰产品类,每一种产品都有特定的装饰效果,可以通过构造器声明装饰哪种类型的ConcreteComponent,从而对其进行装饰。
在博客上看到举的一个例子,觉得举得非常好,下面就是copy过来的
公司门口有一个小摊卖手抓饼和肉夹馍的,有时候中午不想吃饭就会去光顾一下那个小摊,点了手抓饼之后往往还可以在这个基础之上增加一些配料,例如煎蛋,火腿片等等,每个配料的价格都不一样,不管你怎么配配料,最终价格是手抓饼基础价加上每一种所选配料价格的总和。小摊的价格单如下:
如何使用一种设计模式来处理价格计算的问题呢,或许我们可以试试装饰者模式,因为在这里,主体是手抓饼和肉夹馍,而配料则是装饰者,我先用UML类图来描述一下类之间的协作关系。
public abstract class Pacake {
public String foods = "I am a abstract pacake";
public String getfood() {
return foods;
}
public abstract double getprice();
}
public class ShouZhuaBing extends Pacake{
public ShouZhuaBing() {
foods = "手抓饼";
}
@Override
public double getprice() {
return 5.0;
}
}
public class RouJiaMo extends Pacake{
public RouJiaMo() {
foods = "肉夹馍";
}
@Override
public double getprice() {
return 4.0;
}
}
public abstract class Ingredients extends Pacake {
// public abstract String getfoods();
}
public class huotuichang extends Ingredients{
private Pacake pacake;
public huotuichang(Pacake pacake) {
this.pacake = pacake;
}
public String getfood() {
return pacake.getfood()+",火腿肠";
}
@Override
public double getprice() {
return pacake.getprice() + 1.3;
}
}
public class eggs extends Ingredients{
private Pacake pacake;
public eggs(Pacake pacake) {
this.pacake = pacake;
}
@Override
public String getfood() {
return pacake.getfood()+",鸡蛋";
}
@Override
public double getprice() {
return pacake.getprice() + 1.2;
}
}
public class test {
public static void main(String[] args) {
Pacake rouJiaMoPacake = new RouJiaMo();//向上转型
rouJiaMoPacake = new eggs(rouJiaMoPacake);
rouJiaMoPacake = new eggs(rouJiaMoPacake);
rouJiaMoPacake = new huotuichang(rouJiaMoPacake);
System.out.println(rouJiaMoPacake.getClass());
System.out.println(String.format("%s Y%s", rouJiaMoPacake.getfood(),rouJiaMoPacake.getprice()));
}
}
输出结果为:class huotuichang
肉夹馍,鸡蛋,鸡蛋,火腿肠 Y7.7