今天通过网课学习了装饰者模式,总结如下:
1.四部分:
抽象组件conponent:给出一个抽象接口,以规范准接接受附加责任的对象(装饰基类:饮料)
被装饰者concreteconponent:conponent的具体实现,也就是装饰的对象(具体对象:如豆浆,包括 初始价格,初始原料)
装饰者组件decorator:装饰具体组件对象,附加职责(操作:如加钱,加料操作)
具体装饰concreteDecorator:负责给构建对象装饰附加功能(功能:加钱3.5,加料红糖)
实际应用,可以首先先找到需要被改造的类,就是“被装饰者”,然后寻找被装饰者继承的父类,就是“抽象组件”,然后再继承抽象组件构造“装饰者组件”,选择要被重造的方法。
最后在一一对方法进行实现,即具体装饰。然后装配。
优点:
- 装饰者模式比继承有更好的灵活性
- 装饰者模式是动态的,继承是静态的
- 装饰者模式可以用不同的装饰类进行组合,可以产生许多中不同的行为
缺点:
- 会产生很多的小对象,占用内存
- 组合方式多,容易出错
代码演示:
public interface Drink {
// 抽象组件
//价格
public double money();
//品种描述
public String desc();
}
public class Soya implements Drink {
// 被装饰者
@Override
public double money() {
return 5;
}
@Override
public String desc() {
return "纯豆浆";
}
}
public abstract class Decorator implements Drink {
// 装饰器
// 1. 抽象类
// 2. 实现抽象组件的接口
// 3. 持有抽象接口的引用
// 定义私有饮品的接口引用
private Drink drink;
public Decorator(Drink drink) {
this.drink = drink;
}
@Override
public double money() {
return drink.money();
}
@Override
public String desc() {
return drink.desc();
}
}
public class RedBean1 extends Decorator {
// 具体装饰1
public RedBean1(Drink drink) {
super(drink);
}
// 重写money
@Override
public double money() {
return super.money() + 3.5;
}
// 重写描述
@Override
public String desc() {
return super.desc() + "+红豆1";
}
}
public class RedBean2 extends Decorator {
// 具体装饰1
public RedBean2(Drink drink) {
super(drink);
}
// 重写money
@Override
public double money() {
return super.money() + 4;
}
// 重写描述
@Override
public String desc() {
return super.desc() + "+红豆2";
}
}
public class Test {
// 测试
public static void main(String[] args) {
// 开始搭配
// 创建豆浆对象
Drink soya = new Soya();
System.out.println(soya.desc() + “===” + soya.money());
// 加红糖1
Drink readbean1 = new RedBean1(soya);
System.out.println(readbean1.desc() + "===" + readbean1.money());
// 加红糖2
Drink readbean2 = new RedBean1(readbean1);
System.out.println(readbean2.desc() + "===" + readbean2.money());
}