设计模式——装饰者模式(8)

一、定义

  • 指在不改变现有对象结构的情况下,动态地给该对象增加一些职责(即增加其额外功能)的模式。
  • 我们先来看一个快餐店的例子。快餐店有炒面、炒饭这些快餐,可以额外附加鸡蛋、火腿、培根这些配菜,当然加配菜需要额外加钱,每个配菜的价钱通常不太一样,那么计算总价就会显得比较麻烦。如果使用继承的方式存在的问题:扩展性不好如果要再加一种配料(火腿肠),我们就会发现需要给FriedRiceFriedNoodles分别定义一个子类。如果要新增一个快餐品类(炒河粉)的话,就需要定义更多的子类。产生过多的子类
  • 所以我们使用装饰者模式 进行修饰

二、代理模式和装饰模式的区别

  • 相同点
    • 都要实现与目标类相同的业务接口
    • 在两个类中都要声明目标对象
    • 都可以在不修改目标类的前提下增强目标方法
  • 不同点
    • 目的不同 装饰者是为了增强目标对象 静态代理是为了保护和隐藏目标对象
    • 获取目标对象构建的地方不同 装饰者是由外界传递进来,可以通过构造方法传递 静态代理
      是在代理类内部创建,以此来隐藏目标对象
java 复制代码
public abstract class FastFood {
	private float price;
	private String desc;
	public FastFood() {
	}
	public FastFood(float price, String desc) {
	this.price = price;
	this.desc = desc;
	}
	public void setPrice(float price) {
		this.price = price;
	}
	public float getPrice() {
		return price;
	}
	public String getDesc() {
		return desc;
	}
	public void setDesc(String desc) {
		this.desc = desc;
	}
	public abstract float cost(); //获取价格
	}
}
	//炒饭
public class FriedRice extends FastFood {
	public FriedRice() {
		super(10, "炒饭");
	}
	public float cost() {
		return getPrice();
	}
}
//炒面
public class FriedNoodles extends FastFood {
	public FriedNoodles() {
		super(12, "炒面");
	}
	public float cost() {
		return getPrice();
	}
}
//配料类
public abstract class Garnish extends FastFood {
	private FastFood fastFood;
	public FastFood getFastFood() {
		return fastFood;
	}
	public void setFastFood(FastFood fastFood) {
		this.fastFood = fastFood;
	}
	public Garnish(FastFood fastFood, float price, String desc) {
		super(price,desc);
		this.fastFood = fastFood;
	}
}
//鸡蛋配料
public class Egg extends Garnish {
	public Egg(FastFood fastFood) {
		super(fastFood,1,"鸡蛋");
	}
	public float cost() {
		return getPrice() + getFastFood().getPrice();
	}
	@Override
	public String getDesc() {
		return super.getDesc() + getFastFood().getDesc();
	}
}
//培根配料
public class Bacon extends Garnish {
	public Bacon(FastFood fastFood) {
		super(fastFood,2,"培根");
	}
	@Override
	public float cost() {
		return getPrice() + getFastFood().getPrice();
	}
	@Override
	public String getDesc() {
		return super.getDesc() + getFastFood().getDesc();
	}
}
//测试类
public class Client {
	public static void main(String[] args) {
		//点一份炒饭
		FastFood food = new FriedRice();
		//花费的价格
		System.out.println(food.getDesc() + " " + food.cost() + "元");
		System.out.println("========");
		//点一份加鸡蛋的炒饭
		FastFood food1 = new FriedRice();
		food1 = new Egg(food1);
		//花费的价格
		System.out.println(food1.getDesc() + " " + food1.cost() + "元");
		System.out.println("========");
		//点一份加培根的炒面
		FastFood food2 = new FriedNoodles();
		food2 = new Bacon(food2);
		//花费的价格
		System.out.println(food2.getDesc() + " " + food2.cost() + "元");
	}
}
相关推荐
杨充6 小时前
10.可测试性实战设计
设计模式·开源·代码规范
杨充6 小时前
9.重构十二式的实战
设计模式·开源·代码规范
杨充6 小时前
6.设计原则的全景图
设计模式·开源·全栈
杨充7 小时前
2.面向对象的特性
设计模式
杨充7 小时前
7.SOLID原则案例汇
设计模式·开源·全栈
杨充7 小时前
8.反模式与坏味道
设计模式·开源·代码规范
杨充7 小时前
3.接口vs抽象类比较
设计模式
咖啡八杯10 小时前
文法、BNF与AST
java·设计模式·解释器模式·ast·文法
咖啡八杯18 小时前
GoF设计模式——解释器模式
java·后端·spring·设计模式