一、定义
装饰模式就是给一个对象增加一些新的辅助功能,而且是动态的,可以灵活搭配的,要求装饰对象和被装饰对象实现同一个接口,装饰对象持有被装饰对象的实例 (敲黑板,划重点,实现同一个接口)
二、类图
书上的图都是 这样的,
感觉可以简单一点就是 具体的构件和 装饰器都实现Component接口,只是 构件主体里面没有Component com 这个属性,装饰器里面是含有这个属性的,如下图:
三、例子
这个例子就是 食堂打饭吃,一般都是要点一份主食,然后点几个小菜,小菜可以随便搭配,最后结账付钱。
3.1 创建一个 接口Component
public interface Component {
/**
* 描述
* @return
*/
String getDesc();
/**
* 价格
* @return
*/
double getPrice();
}
3.2 创建主食,这里只有米饭和面条
public class Rice implements Component {
@Override
public String getDesc() {
return "米饭";
}
/**
* 米饭5块钱
* @return
*/
@Override
public double getPrice() {
return 5.00;
}
}
public class Noddles implements Component {
@Override
public String getDesc() {
return "面条";
}
@Override
public double getPrice() {
return 7.00;
}
}
3.3 创建装饰类 ,这里是鱼,肉,蔬菜
public class Fish implements Component {
private Component com;
public Fish(Component com) {
this.com = com;
}
@Override
public String getDesc() {
return com.getDesc()+ ",鱼";
}
@Override
public double getPrice() {
return com.getPrice() + 10.00 ;
}
}
public class Meat implements Component {
private Component com;
public Meat(Component com) {
this.com = com;
}
@Override
public String getDesc() {
return com.getDesc() + ",肉";
}
@Override
public double getPrice() {
return com.getPrice() + 15.00;
}
}
public class Vegetables implements Component {
private Component com;
public Vegetables(Component com) {
this.com = com;
}
@Override
public String getDesc() {
return com.getDesc()+ ", 蔬菜";
}
@Override
public double getPrice() {
return com.getPrice() + 3.00;
}
}
3.4 接下来就是 点菜付钱了,
public class Client {
public static void main(String[] args) {
/**
* 米饭
*/
Component rice = new Rice();
rice = new Meat(rice);
rice = new Vegetables(rice);
System.out.println(String.format("种类:%s,total: %s", rice.getDesc(),rice.getPrice()));
/**
*面条
*/
Component no = new Noddles();
no = new Fish(no);
no = new Meat(no);
no = new Vegetables(no);
System.out.println(String.format("种类:%s,total: %s", no.getDesc(),no.getPrice()));
}
}
四、小结
装饰者模式,还是比较好理解的,就是通过共同继承接口,并且把接口作为一个属性,这样就可以 不断的 “嵌套”装饰(用嵌套好像不太合适),这样就实现了灵活搭配的目的。