装饰模式也算一种比较常见的设计模式,工作过程中很少刻意的去实现这种模式,因为这种模式也会带来一些问题。
比如小类太多,组织起来比较麻烦,对客户端完全可见,如果不了解各个类的功能会很乱等等
当然也有很多优点: 可以动态的给类增加一些职责,增加功能更加灵活,比起继承来说也更加具有弹性
下面我们来看看它究竟是什么样子的
以买车业务模型为例(本人未买过车,业务场景纯属臆想)
车里面还有很多装备可以选择,根据不同的选择装饰决定最后到手的价格:
商品 | 价格 |
---|---|
裸车 | 100000 |
加热座椅(可选) | 4000 |
真皮内饰(可选) | 8000 |
蹦迪音响(可选) | 5000 |
package car;
public class Car {
//总价
private int allPrice = 0;
//裸车价格 --实际数值从数据库查询,此处略
private int nakedPrice = 100000;
//加热座椅
private int heatedSeat = 4000;
//真皮内饰
private int dermalInteriors = 8000;
//蹦迪音响
private int bengdiSound = 5000;
public Car() {
this.allPrice += this.nakedPrice;
}
/**
* 添加真皮座椅
*/
public void addHeatedSeat() {
this.allPrice += this.heatedSeat;
}
/**
* 添加真皮内饰
*/
public void addDermalInteriors() {
this.allPrice += this.dermalInteriors;
}
/**
* 添加蹦迪音响
*/
public void addBengdiSound() {
this.allPrice += this.bengdiSound;
}
/**
* 获取总价
*
* @return
*/
public int cost() {
return this.allPrice;
}
}
客户端调用:
package car;
public class Main {
public static void main(String[] args) {
Car car = new Car();
car.addBengdiSound();
System.out.println("总花费价格:" + car.cost());
}
}
output:
花费价格105000
看起来很简洁呢,并且也很好的实现了功能
首先这是我们的场景足够的简单,所涉及的配套组件也比较少,实际中可能针对某个方法可能有很复杂的获取和计算逻辑,组件也会有很多种选择,会造成类爆炸,无法继续维护下去
如果我们使用装饰模式,会带来什么改变呢,会给我们带来什么样的体验呢
声明抽象类(被装饰者和装饰者继承此类,目的对实现方法进行规正)
package car;
public abstract class Car {
public String name;
public abstract String cost();
}
主角:被装饰者类-裸车
package car;
/**
* 被装饰的类 -> 裸车
*/
public class NakeCar extends Car {
//裸车价格 --实际数值从数据库查询,此处略
private int nakedPrice = 100000;
public NakeCar() {
this.name = "裸车";
}
/**
* 获取总价
*
* @return
*/
public String cost() {
return this.name + ":" + this.nakedPrice;
}
}
具体装饰类:
加热座椅
package car;
/**
* 装饰组件
*/
public class HeatedSeat extends Car {
//加热座椅
private int heatedSeat = 4000;
//汽车对象
private Car car;
public HeatedSeat(Car car) {
this.name = "加热座椅";
this.car = car;
}
/**
* 获取价格
*
* @return
*/
public String cost() {
//todo
return this.car.cost() + "||" + this.name + ":" + this.heatedSeat;
}
}
真皮内饰
package car;
public class DermalInteriors extends Car {
//真皮内饰
private int dermalInteriors = 8000;
//汽车对象
private Car car;
public DermalInteriors(Car car) {
this.name = "真皮内饰";
this.car = car;
}
/**
* 获取价格
*
* @return
*/
public String cost() {
//todo
return this.car.cost() + "||" + this.name + ":" + this.dermalInteriors;
}
}
蹦迪音响
package car;
public class BengdiSound extends Car {
//蹦迪音响
private int bengdiSound = 5000;
//汽车对象
private Car car;
public BengdiSound(Car car) {
this.name = "蹦迪音响";
this.car = car;
}
/**
* 获取价格
*
* @return
*/
public String cost() {
//todo
return this.car.cost() + "||" + this.name + ":" + this.bengdiSound;
}
}
客户端调用:
package car;
public class Main {
public static void main(String[] args) {
NakeCar car = new NakeCar();
HeatedSeat heatedSeat = new HeatedSeat(car);
BengdiSound bengdiSound = new BengdiSound(heatedSeat);
System.out.println("总花费价格:" + bengdiSound.cost());
}
}
output:
总花费价格:裸车:100000||加热座椅:4000||蹦迪音响:5000