Chủ Nhật, 31 tháng 3, 2013

Decorator

1. Khái niệm

Decorator pattern sử dụng để thêm các nội dung chức năng vào một object một cách tự động. Decorator cung cấp giải pháp thay thế cho các subclass trong việc mở rộng chức năng.

2. Vấn đề thực tế

Chúng ta ít nhiều cũng đã từng tặng quà cho bạn bè và người thân. Một món quà khi được bày bán thông thường ở dạng thô như con gấu bông, chiếc xe đồ chơi, cây viết...Sau khi mua một món gì đó xong, chúng ta có thể gói quà trong một chiếc hộp. Sau đó có thể bọc giấy gói quà bên ngoài cho đẹp. Như vậy, một món quà cuối cùng được hình thành theo trình tư như sau:
Món quà thô -> đóng hộp -> gói quà

Theo trình tự này, sản phẩm mà chúng ta nhận được sẽ gồm 3 phần: món quà, chiếc hộp và giấy gói. Tất cả kết hợp lại để tạo ra một món quà đẹp hơn, hấp dẫn hơn, hay nói theo một cách khác, chúng ta đã "decor" món quà trông bắt mắt hơn.

Làm thế nào để thể hiện vấn đề trên trong lập trình?

3. Giải pháp

Chúng ta có thể sử dụng decorator pattern để giải quyết vấn đề trên.

Giả sử hành vi của món quà (Gift) là giftRender, khi đó ta sẽ có một interface Giftable thực hiện chức năng là giftRender. Chúng ta cũng sẽ có 1 class có tên là Gift implement Giftable để thực hiện chức năng giftRender. Tên chức năng giftRender sẽ vấn được giữ nguyên, tuy nhiên, tính chất của món quà sẽ được thay đổi, món quà sẽ được bỏ vào hộp và được bọc lại. Khi đó, sản phẩm cuối cùng vẫn có chức năng giftRender và nội dung thực thi trong chức năng đã thay đổi so với lúc nó còn là thể hiện của class Gift.

Decorator pattern không làm thay đổi tên hành vi nhưng nó sẽ làm thay đổi kết quả của hành vi.

Chúng ta có thể xem xét mô hình để hiểu rõ hơn về cấu trúc của Decorator pattern.

4. Mô hình




5. Code sample


public interface Giftable {
    public void giftRender();
}

public class Gift implements Giftable {

    @Override
    public void giftRender() {
        System.out.println("Gift Render function " );
    }
    
}

public abstract class DecoratorGift implements Giftable{
    
    @Override
    public abstract void  giftRender();
    
}

public class BoxGift extends DecoratorGift{
    Giftable gift;
    
    public BoxGift(Giftable g){
        this.gift = g;
    }
    
    @Override
    public void giftRender() {
        gift.giftRender();
        this.boxWrapper();
    }
    
    private void boxWrapper(){
        System.out.println("boxing the gift");
    }
}

public class WrapperGift extends DecoratorGift{
    Giftable gift;
    
    public WrapperGift(Giftable g){
        this.gift = g;
    }
    
    @Override
    public void giftRender() {
        gift.giftRender();
        this.wrapper();
    }
    
    private void wrapper(){
        System.out.println("wrapping the gift");
    }
}

public class DecoratorPattern {
    public static void main(String args[]){
        Giftable gift = new Gift();

        Giftable decor = new BoxGift(gift);
        decor = new WrapperGift(decor);
        decor.giftRender();
    }
}





6. Mối liên hệ với các pattern khác

Không có nhận xét nào:

Đăng nhận xét