1 基本概括

2 主要介绍
2.1 概念
装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。
这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。动态地将责任附加到对象上,若要扩展功能,装饰着提供了比继承更有弹性的替代方案
2.2 主要组成
在装饰模式中,一共有四个角色,分别是 抽象主体、具体主体、抽象装饰、具体装饰。
抽象主体:一个接口或抽象类,以规范需要装饰的主体类,比如:手抓饼
具体主体:具体的需要装饰的主体,比如,普通手抓饼
抽象装饰:持有抽象主体的实例,并实现或继承抽象主体。比如:抽象的材料
具体装饰:具体的装饰品,需继承或实现抽象装饰。表示具体的材料如鸡蛋,香肠等
装饰者设计模式的过程

2.3 应用场景
装饰者在代码程序中适用于以下场景:
1、用于扩展一个类的功能或给一个类添加附加职责。
2、动态的给一个对象添加功能,这些功能可以再动态的撤销。
2.4 优缺点
优点:
- 装饰者比继承灵活,可以在不改变原有对象的情况下动态地给一个对象扩展功能,即插即用非常方便
- 通过不同的装饰器组合,可以实现不同效果
- 装饰者完全遵守开闭原则。
缺点:
- 会增加程序复杂性,会增加更多的类
- 动态装饰时,操作多层装饰复杂
2.5 原则
- 封装变化
- 多用组合少用继承
- 针对接口编程,不针对实现编程
- 为了交互对象之间的松耦合而努力
- 类应该对扩展开放,对修改关闭
3 代码示例
3.1 实现过程
1. 手抓饼接口
/**
* 手抓饼接口
*/
public interface Cake {
public String getCake();
public double getPrice();
}
2. 基本手抓饼实现
/**
* 普通手抓饼5元
*/
public class BaseCake implements Cake{
@Override
public String getCake() {
return "手抓饼";
}
@Override
public double getPrice() {
return 5;
}
}
3. 加蛋装饰器
/**
* 加一个鸡蛋需要加2元
*/
public class AddEggCake implements Cake {
private Cake cake;
public AddEggCake(Cake cake){
this.cake = cake;
}
@Override
public String getCake() {
return cake.getCake() + " + 鸡蛋";
}
@Override
public double getPrice() {
return cake.getPrice() + 2;
}
}
4. 加香肠装饰器
/**
* 加一根肠需要加3元
*/
public class AddSusageCake implements Cake {
private Cake cake;
public AddSusageCake(Cake cake){
this.cake = cake;
}
@Override
public String getCake() {
return cake.getCake() + " + 肠";
}
@Override
public double getPrice() {
return cake.getPrice() + 3;
}
}
5. 测试类
public class Run {
public static void main(String[] args) {
//普通手抓饼
Cake cake1 = new BaseCake();
System.out.println("手抓饼:" + cake1.getCake() + ",需要支付" + cake1.getPrice() + "元");
//手抓饼+鸡蛋
Cake cake2 = new BaseCake();
cake2 = new AddEggCake(cake2);
System.out.println("手抓饼+鸡蛋:" + cake2.getCake() + ",需要支付" + cake2.getPrice() + "元");
//手抓饼+ 2个鸡蛋 + 一根肠
Cake cake3 = new BaseCake();
cake3 = new AddEggCake(cake3);
cake3 = new AddEggCake(cake3);
cake3 = new AddSusageCake(cake3);
System.out.println("手抓饼+2个鸡蛋+一根肠:" + cake3.getCake() + ",需要支付" + cake3.getPrice() + "元");
}
}
一起讨论学习的可以的点下关注,会持续更新,文章有用的话可以收藏,转发,有什么补充可以在下面评论,谢谢