1. 程式人生 > >設計模式(十)裝飾

設計模式(十)裝飾

類結構:

使用裝飾模式實現如下需求:

訂單列表是主體內容,使用頁頭、頁尾來裝飾。

 

1、抽象元件

public abstract class OrderElement {
	
	public abstract void print();
	
}

2、主體元件

import java.util.Vector;

public class OrderList extends OrderElement {
	
	protected Vector<OrderItem> orderItems = new Vector<OrderItem>();

	@Override
	public void print() {
		for (int i = 0; i < orderItems.size(); i++) {
			OrderItem orderItem = orderItems.get(i);
			orderItem.print();
		}
	}

	public void addItem(OrderItem item) {
		orderItems.add(item);
	}

	public void removeItem(OrderItem item) {
		orderItems.remove(item);
	}

	public double getTotal() {
		double total = 0;
		for (int i = 0; i < orderItems.size(); i++) {
			OrderItem item = orderItems.get(i);
			total += item.getSubtotal();
		}
		return total;
	}
	
}

3、抽象裝飾

public abstract class OrderDecorator extends OrderElement {

	protected OrderElement element;

	public OrderDecorator(OrderElement element) {
		this.element = element;
	}
}

4、具體裝飾

public class HeaderDecorator extends OrderDecorator {
	
	public HeaderDecorator(OrderElement element) {
		super(element);
	}

	@Override
	public void print() {
		printHeader();//增加列印頭資訊的功能
		element.print();
	}

	private void printHeader() {
		System.out.println("===================================================");
		System.out.println("商品\t數量\t價格\t小計");
		System.out.println("---------------------------------------------------");
	}
}
public class FooterDecorator extends OrderDecorator {
	
	public FooterDecorator(OrderElement element) {
		super(element);
	}

	@Override
	public void print() {
		element.print();
		printFooter();//增加列印腳資訊的功能
	}

	private void printFooter() {
		System.out.println("---------------------------------------------------");
		System.out.println("總價\t\t\t"+ ((OrderList)element).getTotal());
		System.out.println("===================================================");
	}

}

5、主體元件裡的小項(訂單列表裡的單個商品項)

public class OrderItem {

	private String name;
	private int units;
	private double price;

	public OrderItem(String name, int units, double price) {
		this.name = name;
		this.units = units;
		this.price = price;
	}

	public void print() {
		System.out.println(name + "\t" + units + "\t" + price + "\t" + getSubtotal());
	}

	public double getSubtotal() {
		return price * units;
	}

}

6、消費者

public class Customer {

	public static void main(String[] args) {
		
		OrderList orderList = new OrderList();//訂單列表

		OrderItem orderItem1 = new OrderItem("輪胎",4,154);
		OrderItem orderItem2 = new OrderItem("擋泥板",2,300);

		orderList.addItem(orderItem1);//新增一項商品
		orderList.addItem(orderItem2);//新增一項商品
		
		OrderElement element = new HeaderDecorator(new FooterDecorator(orderList));//使用頁頭、頁尾裝飾訂單列表

		element.print();//列印裝飾後的完整訂單
	}
}

物件結構: