装饰者模式属于结构型模式,它能够动态的将新功能附加到对象上,同时又不改变其结构。在对象功能扩展方面,它比继承更有弹性,装饰者模式也体现了开闭原则(OCP)。java
装饰者和被装饰者有相同的超类型,由于装饰者和被装饰者必须是同样的类型,利用继承是为了达到类型的匹配,而不是利用继承获取行为git
在咖啡店客人想点一杯加两份糖一份牛奶的摩卡咖啡,各个商品的价格以下,咱们须要根据用户点的咖啡、加的配料,动态的计算价格github
商品 | 价格 |
---|---|
拿铁咖啡(LatteCoffee) | 4.5 |
摩卡咖啡(MochaCoffe) | 5.5 |
糖(Sugar) | 1.0 |
牛奶(Milk) | 2.0 |
「实体类」 Coffeeide
public abstract class Coffee{ public String des = "咖啡"; //描述 private float price = 0.0f; //价格 protected abstract float cost(); //计算费用 //省略getter setter方法 }
「被装饰者」LatteCoffee测试
public class LatteCoffee extends Coffee{ public LatteCoffee() { setDes("拿铁咖啡"); setPrice(4.5f); } @Override protected float cost() { return getPrice(); } }
「被装饰者」MochaCoffeethis
public class MochaCoffee extends Coffee { public MochaCoffee() { setDes("摩卡咖啡"); setPrice(5.5f); } @Override protected float cost() { return getPrice(); } }
「抽象装饰者」Decorator设计
public class Decorator extends Coffee { private Coffee coffee; public Decorator(Coffee drink) { this.coffee = drink; } @Override protected float cost() { return getPrice() + coffee.cost(); } @Override public String getDes() { return coffee.getDes() + "加" + super.getDes(); } }
「具体装饰者」SugarDecoratorcode
public class SugarDecorator extends Decorator{ public SugarDecorator(Coffee coffee) { super(coffee); setDes("糖"); setPrice(1.0f); } }
「具体装饰者」MilkDecorator对象
public class MilkDecorator extends Decorator{ public MilkDecorator(Coffee coffee) { super(coffee); setDes("牛奶"); setPrice(2.0f); } }
「测试类」Client继承
public class Client { /** * 点一杯 加两份糖一份牛奶的摩卡咖啡 */ @Test public void test01() { Coffee order = new MochaCoffee(); System.out.println(order.getDes() + ",价格:" + order.cost()); //加两份糖 order = new SugarDecorator(new SugarDecorator(order)); System.out.println(order.getDes() + ",价格:" + order.cost()); //加一份牛奶 order = new MilkDecorator(order); System.out.println(order.getDes() + ",价格:" + order.cost()); } }
「结果」result
摩卡咖啡,价格:5.5 摩卡咖啡加糖加糖,价格:7.5 摩卡咖啡加糖加糖加牛奶,价格:9.5
在上图所示的关系中
具体使用以下:
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("G:\\a.txt"));
一、利用继承设计子类,只能在编译时静态决定,而且全部子类都会继承相同的行为;利用组合扩展对象,就能够在运行时动态的进行扩展。
二、装饰者和被装饰者对象有相同的超类型,因此在任何须要原始对象(被装饰者)的场合,均可以用装饰过的对象代替原始对象。
三、能够用一个或多个装饰者包装一个对象(被装饰者)。
四、装饰者能够在所委托的装饰者行为以前或以后加上本身的行为,以达到特定的目的。
五、被装饰者能够在任什么时候候被装饰,因此能够在运行时动态地、不限量地用你喜欢的装饰者来装饰对象。
p.s. 全部代码和笔记都可在 个人GitHub 中获取,若是对您有帮助的话,能够点个 star 支持一下 🙈