赞
踩
背景
有些人为了早上多睡一会,就会用方便的方式解决早餐问题。有些人早餐可能会吃煎饼,煎饼中可以加鸡蛋,也可以加香肠,但是不管怎么“加码”,都还是一个煎饼。在现实生活中,常常需要对现有产品增加新的功能或美化其外观,如房子装修、相片加相框、咖啡加调料等,都是装饰器模式。
装饰者模式的定义
装饰者(Decorator)模式的定义:指在不改变现有对象结构的情况下,动态地给该对象增加一些职责(即增加其额外功能)的模式。
装饰者模式属于对象结构型模式,也体现了开闭原则(ocp)。
装饰者模式的优缺点
优点:
缺点:装饰器模式会增加许多子类,过度使用会增加程序得复杂性。
装饰者模式的结构
装饰器模式主要包含以下角色。
装饰者模式的结构图
实现星巴克咖啡+调味品的下单,并计算费用
定义抽象构件(Component)角色:定义一个抽象接口以规范准备接收附加责任的对象。
public abstract class Drink { public String dsc; //描述 private float price = 0.0f; //价格 public String getDsc() { return dsc; } public void setDsc(String dsc) { this.dsc = dsc; } public float getPrice() { return price; } public void setPrice(float price) { this.price = price; } //计算费用的抽象方法,由子类实现 public abstract float cost(); }
定义具体构件(ConcreteComponent)角色:实现抽象构件,通过装饰角色为其添加一些职责。
public class Coffee extends Drink{
@Override
public float cost() {
return super.getPrice();
}
}
具体构件(ConcreteComponent)角色1:Espresso 意大利咖啡
public class Espresso extends Coffee{
public Espresso(){
setDsc("意大利咖啡");
setPrice(10.0f);
}
}
具体构件(ConcreteComponent)角色2:LongBlack 美式咖啡1
public class LongBlack extends Coffee{
public LongBlack(){
setDsc("美式咖啡1");
setPrice(9.0f);
}
}
具体构件(ConcreteComponent)角色3:LongBlack 美式咖啡2
public class ShortBlack extends Coffee{
public ShortBlack(){
setDsc("美式咖啡2");
setPrice(8.0f);
}
}
定义抽象装饰(Decorator)角色:继承抽象构件,并包含具体构件的实例,可以通过其子类扩展具体构件的功能。
public class Decorator extends Drink{ //装饰者组合了抽象构件(被装饰者) private Drink obj; public Decorator(Drink obj){ this.obj = obj; } @Override public float cost() { //计算费用:父类的费用 + 自己的费用 return getPrice() + obj.getPrice(); } @Override public String getDsc() { //输出描述:父类的描述 + 自己的描述 return dsc + " " + getPrice() + " " +obj.getDsc(); } }
定义具体装饰(ConcreteDecorator)角色:实现抽象装饰的相关方法,并给具体构件对象添加附加的责任。
具体装饰(ConcreteDecorator)角色1:巧克力 Chocolate
public class Chocolate extends Decorator{
public Chocolate(Drink obj) {
super(obj);
setDsc("巧克力");
setPrice(3.0f);
}
}
具体装饰(ConcreteDecorator)角色2:牛奶 Milk
public class Milk extends Decorator{
public Milk(Drink obj) {
super(obj);
setDsc("牛奶");
setPrice(2.0f);
}
}
具体装饰(ConcreteDecorator)角色3:豆浆 Soy
public class Soy extends Decorator{
public Soy(Drink obj) {
super(obj);
setDsc("豆浆");
setPrice(1.5f);
}
}
编写测试类下咖啡订单,测试装饰者模式:
public class coffeeBar { public static void main(String[] args) { //一杯美式 Drink order1 = new LongBlack(); System.out.println("订单描述:" + order1.getDsc()); System.out.println("订单费用= " + order1.cost()); //一杯美式 + 一份牛奶 order1 = new Milk(order1); System.out.println("订单描述:" + order1.getDsc()); System.out.println("订单费用= " + order1.cost()); //一杯美式 + 2份牛奶 order1 = new Milk(order1); System.out.println("订单描述:" + order1.getDsc()); System.out.println("订单费用= " + order1.cost()); //一杯美式 + 2份牛奶 + 巧克力 order1 = new Chocolate(order1); System.out.println("订单描述:" + order1.getDsc()); System.out.println("订单费用= " + order1.cost()); } }
装饰者模式的应用场景
装饰器模式在 Java 中的体现
装饰器模式在 Java语言中的最著名的应用莫过于 Java I/O 标准库的设计了。例如,InputStream 的子类 FilterInputStream,OutputStream 的子类 FilterOutputStream,Reader 的子类 BufferedReader 以及 FilterReader,还有 Writer 的子类 BufferedWriter、FilterWriter 以及 PrintWriter 等,它们都是抽象装饰类。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。