使用装饰器模式解决煎饼“加码”问题
在《装饰设计模式》一节中,我们提到了煎饼,煎饼中可以加鸡蛋,也可以加香肠,但是不管怎么“加码”,都还是一个煎饼。
下面用代码来模拟给煎饼“加码”的业务场景。为了能让大家更好的理解装饰器模式带来的好处,先来看不用装饰器模式的情况。
首先创建一个煎饼 Pancake 类。
下面用代码来模拟给煎饼“加码”的业务场景。为了能让大家更好的理解装饰器模式带来的好处,先来看不用装饰器模式的情况。
首先创建一个煎饼 Pancake 类。
public class Pancake {
protected String getMsg() {
return "煎饼";
}
public int getPrice() {
return 5;
}
}
然后创建一个加鸡蛋的煎饼 PancakeWithEgg 类。
public class PancakeWithEgg extends Pancake {
@Override
protected String getMsg() {
return super.getMsg() + "一个鸡蛋";
}
@Override
//加1个鸡蛋加1元钱
protected int getPrice() {
return super.getPrice() + 1;
}
}
再创建一个既加鸡蛋又加香肠的 PancakeWithEggAndSausage 类。
public class PancakeWithEggAndSausage extends PancakeWithEgg {
@Override
protected String getMsg() {
return super.getMsg() + "一根香肠";
}
@Override
//加1根香肠加2元钱
protected int getPrice() {
return super.getPrice() + 2;
}
}
最后编写客户端测试代码。
public class Test {
public static void main(String[] args) {
Pancake pancake = new Pancake();
System.out.println(pancake.getMsg() + ",总价格:" + pancake.getPrice());
Pancake pancakeWithEgg = new PancakeWithEgg();
System.out.println(pancakeWithEgg.getMsg() + ",总价格:" + pancakeWithEgg.getPrice());
Pancake pancakeWithEggAndSausage = new PancakeWithEggAndSausage();
System.out.println(pancakeWithEggAndSausage.getMsg() + ",总价格:" + pancakeWithEggAndSausage.getPrice());
}
}
运行结果如下所示:
煎饼,总价格:5
煎饼一个鸡蛋,总价格:6
煎饼一个鸡蛋一根香肠,总价格:8
使用装饰器模式解决煎饼加码问题
下面用装饰器模式来解决上面的问题,首先创建一个煎饼的抽象 Pancake 类。
public abstract class Pancake {
protected abstract String getMsg();
protected abstract int getPrice();
}
创建一个基本的煎饼(或者说是基本套餐)BasePancake 类。
public class BasePancake extends Pancake {
protected String getMsg() {
return "煎饼";
}
public int getPrice() {
return 5;
}
}
然后创建一个扩展套餐的抽象装饰器 PancakeDecorator 类。
public abstract class PancakeDecorator extends Pancake {
//静态代理,委派
private Pancake pancake;
public PancakeDecorator(Pancake pancake) {
this.pancake = pancake;
}
protected abstract void doSomething();
@Override
protected String getMsg() {
return this.pancake.getMsg();
}
@Override
public int getPrice() {
return this.pancake.getPrice();
}
}
创建鸡蛋装饰器 EggDecorator 类。
public class EggDecorator extends PancakeDecorator {
public EggDecorator(Pancake pancake) {
super(pancake);
}
protected void doSomething() {
}
@Override
protected String getMsg() {
return super.getMsg() + "1个鸡蛋";
}
@Override
public int getPrice() {
return super.getPrice() + 1;
}
}
创建香肠装饰器 SausageDecorator 类。
public class SausageDecorator extends PancakeDecorator {
public SausageDecorator(Pancake pancake) {
super(pancake);
}
protected void doSomething() {
}
@Override
protected String getMsg() {
return super.getMsg() + "1根香肠";
}
@Override
public int getPrice() {
return super.getPrice() + 2;
}
}
客户端测试代码如下。
public class Test {
public static void main(String[] args) {
Pancake pancake;
//买一个煎饼
pancake = new BasePancake();
//加一个鸡蛋
pancake = new EggDecorator(pancake);
//再加一个鸡蛋
pancake = new EggDecorator(pancake);
//再加一根香肠
pancake = new SausageDecorator(pancake);
//与静态代理的最大区别就是职责不同
//静态代理不一定要满足 is-a 的关系
//静态代理会做功能增强,同一个职责变得不一样
//装饰器更多考虑的是扩展
System.out.println(pancake.getMsg() + ",总价:" + pancake.getPrice());
}
}
运行结果如下所示。
煎饼1个鸡蛋1个鸡蛋1根香肠,总价:9
最后来看类图,如下图所示。
所有教程
- C语言入门
- C语言编译器
- C语言项目案例
- 数据结构
- C++
- STL
- C++11
- socket
- GCC
- GDB
- Makefile
- OpenCV
- Qt教程
- Unity 3D
- UE4
- 游戏引擎
- Python
- Python并发编程
- TensorFlow
- Django
- NumPy
- Linux
- Shell
- Java教程
- 设计模式
- Java Swing
- Servlet
- JSP教程
- Struts2
- Maven
- Spring
- Spring MVC
- Spring Boot
- Spring Cloud
- Hibernate
- Mybatis
- MySQL教程
- MySQL函数
- NoSQL
- Redis
- MongoDB
- HBase
- Go语言
- C#
- MATLAB
- JavaScript
- Bootstrap
- HTML
- CSS教程
- PHP
- 汇编语言
- TCP/IP
- vi命令
- Android教程
- 区块链
- Docker
- 大数据
- 云计算