标签:
装饰模式又名包装模式。装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案。
装饰模式以对客户端透明的方式动态的给一个对象附加上更多的责任。换言之,客户端并不会觉得对象在装饰前和装饰后有什么不同。装饰模式可以在不使用创造更多子类的情况下,将对象的功能加以扩展。
装饰模式的关键在于这种功能的扩展是透明的。
装饰模式的各个角色有:
在以下情况下应当使用装饰模式:
下面看一个具体的例子,发票系统:
需求:
有一个电子销售系统需要打印出顾客所购买的商品的发票。一张发票可以分为三个部分:
下面就是要求打印出的发票的大致样子:
其中,发票的头部和尾部可以有很多种可能的格式,因此系统的设计必须给出足够的灵活性,使得一个新的头部和尾部格式能够较为容易地插入到系统中;同时本系统的客户端必须可以随意地选择某一个头部格式和某一个尾部格式的组合并与主部格式组合起来。
在这个系统里使用装饰模式,那么发票的头部和尾部都可以分别由具体装饰类来代表。有多少种头部和尾部,就可以有多少种相应的具体装饰类。
/** * 抽象构件角色实现 */ public abstract class Order { protected String customerName; protected Date salesDate; protected Vector<OrderLine> items=new Vector<OrderLine>(); public void print() { for(int i=0;i<items.size();i++) { OrderLine item=items.get(i); item.printLine(); } } public String getCustomerName() { return customerName; } public void setCustomerName(String customerName) { this.customerName = customerName; } public Date getSalesDate() { return salesDate; } public void setSalesDate(Date salesDate) { this.salesDate = salesDate; } public void addItem(OrderLine item) { items.add(item); } public void remoteItem(OrderLine item) { items.remove(item); } public double getGrandTotal() { double amnt=0.0D; for(int i=0;i<items.size();i++) { OrderLine item=items.get(i); amnt+=item.getSubtotal(); } return amnt; } protected String formatCurrency(double amnt) { return NumberFormat.getCurrencyInstance().format(amnt); } }
/** * 具体构件角色 */ public class SalesOrder extends Order { public SalesOrder() { } public void print() { super.print(); } }
/** * 抽象装饰角色 */ public class OrderDecorator extends Order { //抽象装饰角色,持有一个将要附加责任的类 protected Order order; public OrderDecorator(Order order) { this.order=order; this.setSalesDate(order.getSalesDate()); this.setCustomerName(order.getCustomerName()); } public void print() { super.print(); } }
/** * 具体装饰角色 */ public class HeaderDecorator extends OrderDecorator { public HeaderDecorator(Order anOrder) { super(anOrder); } public void print() { this.printHeader(); super.order.print(); } private void printHeader() { System.out.println("***\tINVOICE\t***"); System.out.println("XYZ Incorporated\nDate of Sale:"); System.out.println(order.getSalesDate()); System.out.println("==========================="); System.out.println("Item\t\tUnits\tUnit Price\tSubtotal"); } }
/** * 具体装饰角色 */ public class FooterDecorator extends OrderDecorator { public FooterDecorator(Order anOrder) { super(anOrder); } public void print() { super.order.print(); printFooter(); } public void printFooter() { System.out.println("==========================="); System.out.println("Total\t\t\t\t\t\t"+formatCurrency(order.getGrandTotal())); } }
/** * OrderLine类是一个销售单的购物清单中的一行 */ public class OrderLine { private String itemName; private int units; private double unitPrice; public void printLine() { System.out.println(itemName+"\t\t"+units+"\t\t"+formatCurrency(unitPrice)+"\t\t"+formatCurrency(getSubtotal())); } public double getSubtotal() { return unitPrice * units; } private String formatCurrency(double amnt) { return NumberFormat.getCurrencyInstance().format(amnt); } public String getItemName() { return itemName; } public void setItemName(String itemName) { this.itemName = itemName; } public int getUnits() { return units; } public void setUnits(int units) { this.units = units; } public double getUnitPrice() { return unitPrice; } public void setUnitPrice(double unitPrice) { this.unitPrice = unitPrice; } }
/** * 示意性的客户端源代码 */ public class Client { private static Order order; public static void main(String[] args) { order=new SalesOrder(); order.setSalesDate(new Date()); order.setCustomerName("XYZ Repair Shop"); OrderLine line1=new OrderLine(); line1.setItemName("wire"); line1.setUnitPrice(154.23); line1.setUnits(4); order.addItem(line1); OrderLine line2=new OrderLine(); line2.setItemName("iphone"); line2.setUnitPrice(1499); line2.setUnits(1); order.addItem(line2); order=new HeaderDecorator(new FooterDecorator(order)); order.print(); } }
标签:
原文地址:http://www.cnblogs.com/xtsylc/p/4744330.html