目录
一、装饰者模式的定义与类型
- 一、装饰者模式的定义与类型
- 二、装饰者模式的适用场景
- 三、装饰者模式的优点
- 四、装饰者模式的缺点
- 五、装饰者模式相关的设计模式
- 六、普通示例:
- 七、普通示例演进,使用装饰者模式示例:
1、定义
- 在不改变原有对象的基础之上,将功能附加到对象上
- 提供了比继承更具有弹性的替代方法(扩展原有对象功能)
2、类型
- 结构型
- 扩展一个类的功能或给一个类添加附加职责
- 动态的给一个对象添加功能,这些功能可以在动态的撤销
- 继承的有力补充,比继承灵活,不改变原有对象的情况下给一个对象扩展功能
- 通过使用不同装饰类以及这些装饰类的排列组合,可以实现不同效果
- 符合开闭原则
- 会出现更多的代码,更多的类,增加程序复杂性
- 动态装饰时,多层装饰时会更复杂
- 装饰者模式和代理模式
- 装饰者模式和适配器模式
示例描述:创建一个煎饼类、加鸡蛋的煎饼类,加鸡蛋和香肠的煎饼类,并获取相应的描述和价格 该示例如果煎饼加2个、3、4、5个等鸡蛋或者煎饼的话,扩展会麻烦
1、定义一个煎饼类
package com.rf.designPatterns.structural.decorator.v1;
/**
* @description: 煎饼类
* @author: xiaozhi
* @create: 2020-06-22 21:30
*/
public class Pancakes {
//获取描述的方法 protected在子类中可以重写
protected String getDesc(){
return "煎饼";
}
//获取价格的方法
protected int getPrice(){
return 8;
}
}
2、定义一个加一个鸡蛋的煎饼类
package com.rf.designPatterns.structural.decorator.v1;
/**
* @description: 加一个鸡蛋的煎饼类
* @author: xiaozhi
* @create: 2020-06-22 21:35
*/
public class PancakesWithEgg extends Pancakes{
@Override
public String getDesc() {
return super.getDesc()+"加一个鸡蛋";
}
@Override
public int getPrice() {
return super.getPrice()+1;
}
}
3、 定义一个加一个鸡蛋并且加一个香肠的煎饼类
package com.rf.designPatterns.structural.decorator.v1;
/**
* @description: 加一个鸡蛋并且加一个香肠的煎饼类
* @author: xiaozhi
* @create: 2020-06-22 21:37
*/
public class PancakesWithSausage extends PancakesWithEgg{
@Override
public String getDesc() {
return super.getDesc()+"加一个香肠";
}
@Override
public int getPrice() {
return super.getPrice()+2;
}
}
4、定义一个测试类
package com.rf.designPatterns.structural.decorator.v1;
/**
* @description: 测试类
* @author: xiaozhi
* @create: 2020-06-22 21:38
*/
public class Test {
public static void main(String[] args) {
Pancakes pancakes = new Pancakes();
System.out.println(pancakes.getDesc()+"销售价格为:"+pancakes.getPrice());
Pancakes pancakesWithEgg = new PancakesWithEgg();
System.out.println(pancakesWithEgg.getDesc()+"销售价格为:"+pancakesWithEgg.getPrice());
Pancakes pancakesWithSausage = new PancakesWithSausage();
System.out.println(pancakesWithSausage.getDesc()+"销售价格为:"+pancakesWithSausage.getPrice());
}
}
5、输出效果图下图: 6、类图如下:
装饰者模式4个角色:抽象的实体类、具体的实体类、抽象的装饰者、确定的装饰者 在该示例中:被装饰者是煎饼;装饰者是鸡蛋和香肠
1、定义一个抽象的煎饼实体类
package com.rf.designPatterns.structural.decorator.v2;
/**
* @description: 定义一个抽象的煎饼实体类
* @author: xiaozhi
* @create: 2020-06-22 22:22
*/
public abstract class ABpancakes {
//获取描述的抽象方法
protected abstract String getDesc();
//获取价格的抽象方法
protected abstract int getPrice();
}
2、定义一个具体的煎饼实体类,继承抽象的煎饼实体类,并重写方法
package com.rf.designPatterns.structural.decorator.v2;
/**
* @description: 定义一个具体的煎饼实体类,继承抽象的煎饼实体类,并重写方法
* @author: xiaozhi
* @create: 2020-06-22 22:25
*/
public class Pancakes extends ABpancakes{
@Override
protected String getDesc() {
return "煎饼";
}
@Override
protected int getPrice() {
return 8;
}
}
3、定义一个抽象的装饰者类,继承抽象的煎饼实体类并重写方法,该类是否定义为抽象类,因场景而定
package com.rf.designPatterns.structural.decorator.v2;
/**
* @description: 定义一个抽象的装饰者类,继承抽象的煎饼实体类并重写方法
* 该类是否定义为抽象类,因场景而定
* @author: xiaozhi
* @create: 2020-06-22 22:28
*/
public class AbstractDecorator extends ABpancakes{
//通过构造方法注入抽象的煎饼实体类
private ABpancakes aBpancakes;
public AbstractDecorator(ABpancakes aBpancakes) {
this.aBpancakes = aBpancakes;
}
@Override
protected String getDesc() {
return this.aBpancakes.getDesc();//获取描述
}
@Override
protected int getPrice() {
return this.aBpancakes.getPrice();//获取价格
}
}
4、定义一个鸡蛋的装饰者类,继承抽象的装饰者类,并实现抽象的装饰者类的构造器
package com.rf.designPatterns.structural.decorator.v2;
/**
* @description: 定义一个鸡蛋的装饰者类,继承抽象的装饰者类,并实现抽象的装饰者类的构造器
* @author: xiaozhi
* @create: 2020-06-22 22:31
*/
public class EggDecorator extends AbstractDecorator{
public EggDecorator(ABpancakes aBpancakes) {
super(aBpancakes);
}
@Override
protected String getDesc() {
return super.getDesc()+"加一个鸡蛋,";
}
@Override
protected int getPrice() {
return super.getPrice()+1;
}
}
5、定义一个香肠的装饰者类,继承抽象的装饰者类,并实现抽象的装饰者类的构造器
package com.rf.designPatterns.structural.decorator.v2;
/**
* @description: 定义一个香肠的装饰者类,继承抽象的装饰者类,并实现抽象的装饰者类的构造器
* @author: xiaozhi
* @create: 2020-06-22 22:31
*/
public class SausageDecorator extends AbstractDecorator{
public SausageDecorator(ABpancakes aBpancakes) {
super(aBpancakes);
}
@Override
protected String getDesc() {
return super.getDesc()+"加一根香肠,";
}
@Override
protected int getPrice() {
return super.getPrice()+2;
}
}
6、定义一个测试类
package com.rf.designPatterns.structural.decorator.v2;
/**
* @description: 测试类
* @author: xiaozhi
* @create: 2020-06-22 22:38
*/
public class Test {
public static void main(String[] args) {
ABpancakes aBpancakes;//创建一个抽象的煎饼实体类
aBpancakes=new Pancakes();//创建一个具体的煎饼实体类
aBpancakes=new EggDecorator(aBpancakes);//创建一个加鸡蛋的煎饼类
aBpancakes=new EggDecorator(aBpancakes);//再创建一个加鸡蛋的煎饼类
aBpancakes=new SausageDecorator(aBpancakes);//再创建一个加香肠的煎饼类
System.out.println(aBpancakes.getDesc()+" 销售价格:"+aBpancakes.getPrice());
}
}
7、输出结果如下:
8、类图如下: