装饰者模式

需求概述

  • 需求引入:星巴克咖啡订单项目
    《1》咖啡种类/单品咖啡:Espresson(意大利浓咖啡)、ShortBlack、LongBlack(美式咖啡)、Decaf(无因咖啡)
    《2》调料:Milk,Soy(豆浆)、Chocolate
    《3》要求在扩展新的咖啡种类时,具有良好的扩展性,改动方便,维护方便
    《4》使用OO的来计算不同种类咖啡的费用:客户可以点单品咖啡,也可以单品咖啡+调料组合

我们传统使用的方法(性能较差)

  • 方案一分析
    Drink是一个抽象类,表示饮料
    des就是对咖啡的描述,比如咖啡的名字
    cost()方法时计算费用,Drink类中做成一个抽象方法
    Decaf就是单品咖啡,继承Drink,并实现cost
    Espress&&Milk就是单品咖啡+调料,这个组合很多
    问题:这样设计,会有很多类要写,当我们增加一个单品咖啡或者新的调料,需要增加很多新的类
  • 方案二分析
    《1》前面分析到方案因为咖啡单品+调料组合会造成累的倍增,因此可以做改进,将调料内置到Drink类,这样就不会造成数量过多。从而提高项目的维护性。
    《2》存在问题:这种方法可以控制类的数量,不至于造成很多的类
    在增加或者删除调料种类时,代码的维护量还是很大
    在考虑用户可以添加多分调料时,可以将HasMilk返回一个对应的int
    所以考虑使用装饰者模式

装饰者模式的概述

  • 装饰者模式定义:动态的将新功能附加到对象上。在对象功能扩展方面,它比继承更有弹性,装饰者模式也体现了开闭原则(OCP)。
  • 装饰者模式(Decorator)原理:
    《1》装饰者就像打包一个快递
    主题:比如:陶瓷、衣服(Component)
    包装:比如:报纸填充,封面,木板(Decorator)
    《2》Component
    Component:主体,比如类似前面的Drink
    《3》ConCreteComponent和Decorator
    ConCreteComponent:具体的主体,比如前面的各个单品咖啡
    Decorator:装饰者,比如调料
    《4》在如图的Component与ConcreteComponent之间,如果ConcreteComponent类很多,还可以设计一个缓冲层,将共有的部分提取出来,抽象成一个类。
  • 解题思路
    在这里插入图片描述
    在这里插入图片描述

装饰者模式的实现

  • 具体代码实现

//抽象的饮品类
public abstract class Drink {
	
	public String des;//饮品描述
	private float price=0.0f;//饮品价格
	
	public String getDes() {
		return des;
	}
	public void setDes(String des) {
		this.des = des;
	}
	
	public float getPrice() {
		return price;
	}
	public void setPrice(float price) {
		this.price = price;
	}
	
	
	//计算方法的抽象方法
	public abstract float cost();//这个是费用,需要子类来实现
	
	
}



//咖啡类属于饮品大类
public class Coffee extends Drink {

	@Override
	public float cost() {//得到自身的价格
		return super.getPrice();
	}
	
}
//一种咖啡,继承(Coffee)咖啡类,间接继承了(Drink)饮品大类,拥有价格,描述等信息
public class Espresso extends Coffee {

	public Espresso() {
		setDes("意大利咖啡");
		setPrice(6.0f);
	}
	
}

//单品咖啡
public class LongBlack extends Coffee{

	public LongBlack() {
		setPrice(5.0f);
		setDes("longblack");
		
	}
	
}

//单品咖啡
public class ShortBlack extends Coffee{

	public ShortBlack() {
		setDes("shortblack");
		setPrice(4.0f);
	}
	
}

//具体的装饰类,这里就是调味品
public class Chocolate extends  Decorator{

	public Chocolate(Drink obj) {
		super(obj);
		setDes("巧克力");
		setPrice(3.0f);//调味品的价格
	}

}

//具体的装饰类,这里就是调味品
public class Milk extends  Decorator{

	public Milk(Drink obj) {
		super(obj);
		setDes("牛奶");
		setPrice(2.0f);//调味品的价格
	}

}

//具体的装饰类,这里就是调味品
public class Soy extends  Decorator{

	public Soy(Drink obj) {
		super(obj);
		setDes("豆浆");
		setPrice(1.0f);//调味品的价格
	}

}

装饰者模式在JDK应用的源码分析

  • Java的IO结构,FilerInputStream就是一个装饰者,BufferInputStream继承FilerInputStream,是一个具体的装饰类,然后FilerInputStream继承了InputStream ,组合了一个InputSteam为被装饰的对象。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  • 分析总结
package com.design.zhuangshizhe;

import java.io.DataInputStream;
import java.io.FileInputStream;

public class Test {
	public static void main(String[] args) throws Exception {
		
		//FileInputStream是一个装饰类
		/*//分析:1.inputStream是抽象类,类似我们前面讲的Drink
		
		*2.FileInputStream是InputStream的子类,类似我们前面的Decaf,LongBlack
		*3.FilterInputStream是InputStream的子类,类似于Decorator,修饰着大类
		*4.DataInputStream是FilterStream的子类,具体的装饰者,类似于前面的milk,chocolate
		*5.FilterInputStream类有protected volatile InputStream in ;即包含被装饰者
		*6.在jdk的IO体系中,就是装饰者模式
		*
		*/
		
		DataInputStream data=new DataInputStream(new FileInputStream("E:/a.txt"));
		data.read();
		data.close();
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值