作用
装饰者模式是为已有功能动态地添加更多功能地一种方式。当系统需要新功能的时候,是向旧的类中添加新的代码。这些新加的代码通常装饰了原有类的核心职责或主要行为。装饰者模式他把要装饰的功能放在单独的类中,并让这个类包装他所需要装饰的对象,因此,当需要执行特殊行为时,客户代码就可以在运行时根据需要有选择地、按顺序地使用装饰功能包装对象了。(核心思想)
应用场景
比如装修房子。 再给房子做完水电后,还要买卧室的门、床、电器等来将房子点缀,达到更宜居的效果。
代码实现
//定义房子的装修, 怎么装修让子类(用户)去实现
public abstract class House {
protected abstract String getMsg();
protected abstract double getPrice();
}
//简装一下房子
public class SimpleDecorator extends House {
@Override
protected String getMsg() {
return "简单装修";
}
@Override
protected double getPrice() {
return 50000;
}
}
//在给房子增加别的装饰
public abstract class ComplexDecorator extends House{
//<b>复杂的装修是基于被装修过的房子上累积增加装饰的, 所以要将已经点缀过的对象通过构造方法传过来</b>
private House house;
public ComplexDecorator(House house) {
this.house = house;
}
@Override
protected String getMsg() {
return this.house.getMsg();
}
@Override
protected double getPrice() {
return this.house.getPrice();
}
}
//给房子加个门
public class DoorDecorator extends ComplexDecorator {
public DoorDecorator(House house) {
super(house);
}
@Override
protected String getMsg() {
return super.getMsg() + " +1个门";
}
@Override
protected double getPrice() {
return super.getPrice() + 800;
}
}
public class BedDecoractor extends ComplexDecorator{
public BedDecoractor(House house) {
super(house);
}
@Override
protected String getMsg() {
return super.getMsg() + " +1张床";
}
@Override
protected double getPrice() {
return super.getPrice() + 2000;
}
}
public class ElectricalDecorator extends ComplexDecorator {
public ElectricalDecorator(House house) {
super(house);
}
@Override
protected String getMsg() {
return super.getMsg() + " 购买家电";
}
@Override
protected double getPrice() {
return super.getPrice() + 10000;
}
}
//测试
public class HouseTest extends Observable {
public static void main(String[] args) {
House house ;
//先简装
house = new SimpleDecorator();
//为每个卧室装个门(三室一厅的房子)
house = new DoorDecorator(house);
house = new DoorDecorator(house);
house = new DoorDecorator(house);
//给主卧次卧各准备一张床
house = new BedDecoractor(house);
house = new BedDecoractor(house);
//购买家电
house = new ElectricalDecorator(house);
System.out.println(house.getMsg() + " " +house.getPrice());
}
}