定义
在不改变现有对象结构以及不使用继承的情况下,给对象扩展功能。它是通过创建装饰对象,然后包裹目标对象的方式来完成。
使用继承的缺点
我们下面给出案例:
public class EggCake {
public String getDesc() {
return "鸡蛋饼";
}
public double getPrice() {
return 3;
}
}
public class EggCakePlusA extends EggCake {
@Override
public String getDesc() {
String desc = super.getDesc();
return desc + " + 煎蛋";
}
@Override
public double getPrice() {
double price = super.getPrice();
return price + 2;
}
}
public class EggCakePlusB extends EggCake {
@Override
public String getDesc() {
String desc = super.getDesc();
return desc + " + 火腿肠";
}
@Override
public double getPrice() {
double price = super.getPrice();
return price + 3.5;
}
}
public class Test {
public static void main(String[] args) {
EggCake eggCake = new EggCake();
System.out.println(eggCake.getDesc() + " 销售价格:" +
eggCake.getPrice());
EggCakePlusA eggCakePlusA = new EggCakePlusA();
System.out.println(eggCakePlusA.getDesc() + " 销售价格:" +
eggCakePlusA.getPrice());
EggCakePlusB eggCakePlusB = new EggCakePlusB();
System.out.println(eggCakePlusB.getDesc() + " 销售价格:" +
eggCakePlusB.getPrice());
}
}
运行结果:
如果这时候要既加煎蛋,又加火腿肠,是不是又要写一个类;加2个煎蛋,1根火腿肠,也要写?这样子扩展,类就无止境了,这就是使用继承的缺点。
角色定义
基类角色:被装饰者角色和装饰者角色共同的父类,通常是一个抽象类
被装饰者角色:继承基类,通过装饰者增强
抽象装饰者角色:继承基类,并包含一个被装饰者的实例
具体装饰者角色:继承抽象装饰者,重写方法,方法内部使用被装饰者实例和额外的代码来实现增强
代码实现
/**
* 基类角色:饼
*/
public abstract class Cake {
public abstract String getDesc();
public abstract double price();
}
/**
* 被装饰者:鸡蛋饼
*/
public class EggCake extends Cake {
@Override
public String getDesc() {
return "鸡蛋饼";
}
@Override
public double price() {
return 4.5;
}
}
/**
* 抽象装饰者:加料
*/
public class Condiment extends Cake{
protected Cake cake;
public Condiment(Cake cake) {
this.cake = cake;
}
@Override
public String getDesc() {
return this.cake.getDesc();
}
@Override
public double price() {
return this.cake.price();
}
}
/**
* 具体装饰者:煎蛋
*/
public class FriedEgg extends Condiment{
public FriedEgg(Cake cake) {
super(cake);
}
@Override
public String getDesc() {
return super.getDesc() + " + 煎蛋";
}
@Override
public double price() {
return super.price() + 1.5;
}
}
/**
* 具体装饰者:火腿
*/
public class Ham extends Condiment{
public Ham(Cake cake){
super(cake);
}
@Override
public String getDesc() {
return super.getDesc() + " + 火腿";
}
@Override
public double price() {
return super.price() + 3.0;
}
}
/**
* 测试类
*/
public class Test {
public static void main(String[] args) {
Cake cake = new EggCake();
System.out.println(cake.getDesc() + ":" + cake.price());
cake = new FriedEgg(cake);
cake = new Ham(cake);
cake = new FriedEgg(cake);
System.out.println(cake.getDesc() + ":" + cake.price());
}
}
运行结果如下:
优缺点
优点:
- 增强对象的功能比采用继承方式更加灵活
- 多个不同的具体装饰者,可以搭配出任意的组合
- 装饰者和被装饰者解耦,可以独立发展
缺点:
- 仍然需要编写许多的具体装饰者
- 过多的装饰,会让程序变得复杂