设计模式——装饰者模式(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() + "元");
	}
}
相关推荐
海特伟业12 小时前
隧道调频广播覆盖-隧道调频广播无线覆盖系统建设要点、难点分析与解决应对
运维·设计模式
sg_knight12 小时前
设计模式实战:享元模式(Flyweight)
python·设计模式·享元模式·flyweight
Swift社区15 小时前
AI 时代,ArkUI 的设计模式会改变吗?
人工智能·设计模式
数据中穿行15 小时前
访问者设计模式全方位深度解析
设计模式
宁雨桥16 小时前
前端设计模式面试题大全
前端·设计模式
数据中穿行17 小时前
迭代器设计模式全方位深度解析
设计模式
数据中穿行17 小时前
观察者设计模式全方位深度解析
设计模式
程序员Terry17 小时前
别老写重复代码了!模版方法模式一次讲透
java·设计模式
数据中穿行17 小时前
建造者模式全方位深度解析
设计模式