设计模式学习(七)装饰者模式

装饰者模式

前言

  • 通过一个案例来解释为什么要用装饰模式
  • 在这里插入图片描述
  • 要完成这个案例的方法有很多种,传统方式是这样解决的:
    • 在这里插入图片描述
    • 在这里插入图片描述
  • 根据上面一个方案的问题,提出了一个更好一点的方案:
    • 在这里插入图片描述
    • 但是方案二还是有问题,在增加和删除调料的时候,代码的维护量还是很多。
  • 所以就是用装饰者模式去解决这一案例

基本介绍

  • 装饰者模式: 动态的 将新功能 附加到对象上 。在对象功能扩展方面,它比继承更有弹性,装饰者模式也体现了开闭原则
  • 这里提到的动态的将新功能附加到对象 和 ocp 原则 ,在后面的应用实例上会以代码的形式体现。
  • 在这里插入图片描述

具体案例实现

  • 类图在这里插入图片描述
  • 代码实现:
//饮品的抽象类
public abstract class Drink {
	
	//描述
	public String des;
	//价格
	public double price;
	public String getDes() {
		return des;
	}
	public void setDes(String des) {
		this.des = des;
	}
	public Double getPrice() {
		return price;
	}
	public void setPrice(Double price) {
		this.price = price;
	}
	
	//计算价格
	public abstract double cost();
	//打印咖啡名字
	public abstract String print();
	
}

/* 咖啡品种 */
//咖啡抽象类
public class Coffee extends Drink{

	//返回本来咖啡的价格
	@Override
	public double cost() {
		return super.price;
	}
	//打印咖啡名字
	@Override
	public String print() {
		return des;
	}

}
//蓝山咖啡
public class BlueMountain extends Coffee{
	public BlueMountain() {
		setDes("蓝山咖啡");
		setPrice(10.0);
	}

}

//意大利咖啡
public class Espresso extends Coffee{
	
	public Espresso() {
		setDes("意大利咖啡");
		setPrice(6.0);
	}

}

/* 调料 */
//调料
public class Decorator extends Drink{
	
	//已经点了饮料,想要在添加调料
	private Drink drink;
	
	public Decorator(Drink drink) {
		this.drink = drink;
	}

	//计算费用
	@Override
	public double cost() {
		return drink.cost()+price;
	}
	//打印咖啡样式
	@Override
	public String print() {
		return des + drink.des;
	}
	

}
//牛奶
public class Milk extends Decorator{

	public Milk(Drink drink) {
		super(drink);
		setDes("牛奶");
		setPrice(1.0);
	}
	

}
//巧克力
public class Chocolate extends Decorator{

	public Chocolate(Drink drink) {
		super(drink);
		setDes("巧克力");
		setPrice(2.0);

	}
	
	

}

//客户端
//客户端
public class Client {
	public static void main(String[] args) {
		//1. 先点一杯蓝山咖啡
		Drink order = new BlueMountain();
		System.out.println(order.print()+" 价格为:"+order.cost());
		//2. 加牛奶
		order = new Milk(order);
		System.out.println(order.des+" 价格为:"+order.price);
		System.out.println(order.print()+" 价格为:"+order.cost());
		//2. 加巧克力
		order = new Chocolate(order);
		System.out.println(order.des+" 价格为:"+order.price);
		System.out.println(order.print()+" 价格为:"+order.cost());
		
	}
}
  • 结果:
    在这里插入图片描述

装饰者模式总结

  • 装饰者模式的优点:
    • 目的在于扩展对象的功能。装饰者模式提供比继承更好的灵活性。装饰是动态的,运行时可以修改的;继承是静态的,编译期便已确定好。
    • 通过使用不同的装饰类及对它们的排列组合,可以创造出许多不同行为的组合。
  • 装饰者模式的缺点:
    • 利用装饰者模式,常常造成设计中有大量的小类,数量太多,会造成使用此API的人带来困扰,不容易理解。
    • 采用装饰者在实例化组件时,将增加代码复杂度。一旦使用装饰者,不仅要实例化组件,同时要将组件实例包装进装饰者。
    • 调试时不易排查错误。
  • 适用场景:
    • 需要扩展一个类的功能, 或给一个类增加附加功能。
    • 需要动态地给一个对象增加功能, 这些功能可以再动态地撤销。
    • 需要为一批的兄弟类进行改装或加装功能, 当然是首选装饰模式
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值