一、基本介绍
- 装饰者模式:动态的将新功能附加到对象上。在对象功能扩展方面,它比继承更
有弹性。 - 装饰者模式就像打包一个快递。
主体(Component):比如:陶瓷、食物
包装(Decorator):比如:报纸、泡沫
二、代码实现
(1)创建快递主体抽象类和具体快递类
public abstract class Delivery {
private String describe;
private float value = 0.0f;
public String getDescribe() {
return describe;
}
public void setDescribe(String describe) {
this.describe = describe;
}
public float getValue() {
return value;
}
public void setValue(float price) {
this.value = price;
}
public abstract float value();
}
public class Cloth extends Delivery {
public Cloth() {
setDescribe("衣物");
setValue(3.0f);
}
@Override
public float value() {
return getValue();
}
}
public class Food extends Delivery {
public Food() {
setDescribe("食物");
setValue(2.0f);
}
@Override
public float value() {
return getValue();
}
}
(2)创建快递包装类和具体包装类
public class Package extends Delivery {
private Delivery delivery;
public Package(Delivery delivery) {
this.delivery = delivery;
}
@Override
public float value() {
return super.getValue() + delivery.value();
}
@Override
public String getDescribe() {
return super.getDescribe() + ":" + super.getValue() + " && " + delivery.getDescribe()+":" + delivery.getValue();
}
}
public class NewsPaper extends Package {
public NewsPaper(Delivery delivery) {
super(delivery);
setDescribe("报纸");
setValue(1.0f);
}
}
public class Foam extends Package{
public Foam(Delivery delivery) {
super(delivery);
super.setDescribe("泡沫");
setValue(4f);
}
}
(3)测试
public class Courier {
public static void main(String[] args) {
// 1. 快递只有衣服
Delivery delivery = new Cloth();
System.out.println("费用=" + delivery.value());
System.out.println("描述=" + delivery.getDescribe());
//2. 快递是报纸包着衣服
Delivery delivery2 = new NewsPaper(delivery);
System.out.println("费用=" + delivery2.value());
System.out.println("描述=" + delivery2.getDescribe());
}
}
三、UML类图
四、装饰者模式小结
- 优点:装饰类和被装饰类可以独立发展,不会相互耦合,可以动态扩展一个实现类的功能。
- 缺点:多层装饰比较复杂。
五、装饰者模式和桥接模式的区别
- 相同点:可以处理类爆炸的情况
- 不同点:
(1)装饰者模式中装饰类需要继承接口的同时需要聚合接口,桥接模式中桥接类需要聚合接口。
(2)装饰者模式可以想象成一个套娃,每套一个娃就相当于添加了一个装饰的对象。桥接模式可以想象成一座桥,用于沟通不同属性组成一个新的对象。
(3)一般情况下,如果一个对象有多种属性,可以使用桥接模式,如果一个对象可以添加多种属性,可以使用装饰者模式。