Thứ Tư, 26 tháng 12, 2018

Decorator Pattern

Decorator Pattern là gì? Hừm, mình sẽ cho bạn định nghĩa dễ hiểu trước. Giả sử bạn có 1 đối tượng, và bạn muốn đối tượng đó thực hiện 1 tác vụ nào đó.
Nhưng đôi lúc, bạn lại muốn respond của bạn là 1 cái gì đó khác hơn, 1 cái gì đó được thêm mắm thêm muối vào cho mặn mà hơn, thì bạn phải làm thế nào? À, đúng rồi! Bạn sẽ thay đổi cách mà đối tượng respond bằng cách sửa code của đối tượng. Nhưng sau một thời gian, bạn lại muốn respond khác hơn, 1 chút cay nồng hơn, thì bạn phải làm sao? À, bạn lại thay đổi code của đối tượng tiếp. Và bạn chợt nhận ra, sao cái cách này nó lìn lìn thế nào ấy nhỉ? Đúng rồi đấy, vậy nên người ta mới nghĩ ra 1 cái pattern gọi là decorator patter. Cái loại này sẽ tạo ra 1 cái decorator bao bọc cái đối tượng ban đầu, sau đó nói lấy cái respond của cái đối tượng đó rắc thêm chút mắm muối rồi mới trả ngược lại cho bạn.
Như trong hình trên, cái decorator sẽ lấy respond từ object, sau đó nó sẽ rắc thêm chút muối, tẩm thêm 1 chút mắm rồi mới trả về cho bạn. Nếu như bạn muốn thêm tí cay nồng ư? Dễ thôi!
Chỉ cần thêm 1 cái decorator bao bọc bên ngoài, rồi đổ thêm tí ớt là xong. Phương pháp bao bọc thêm thắt này người ta gọi là decorator pattern.
Decorator Pattern: gắn thêm 1 vài tính năng cho 1 đối tượng 1 cách linh động. Loại pattern này cho phép ta mở rộng lớp con 1 cách linh động hơn
Arggg, sao mình ghét mấy cái khái niệm khô khan này thế nhỉ? hừm, mình sẽ bay vào ví dụ cho các bạn hiểu ngay nà. Có bạn nào đi uống trà sữa chưa? Ai nói chưa thì đi mua 1 ly đi rồi về đọc tiếp nhá. Khi bạn vào 1 quán chà sữa, bạn order sẽ gọi loại trà sữa đầu tiên. Ví dụ bạn gọi chà sữa nhà làm, hoặc có bạn thì gọi chà sữa đài loan. Sau khi bạn order loại trà sữa xong, mấy bé thu ngân sẽ kiểu gạ gẫm:
- ahihi, anh có muốn dùng thêm topping ko ạ?
- có những loại topping gì em?
- ahihi, có nhiều loại topping lắm, anh cứ đọc ở menu ạ.
- vậy lấy anh thêm chân châu chắng và hạt thủy tinh nha
- ahihi, ok anh.
- ahihi, dm em. làm nhanh anh còn về đọc design pattern=))
Đó là 1 quá trình order trà sữa điển hình. Và khi tầm tờ hóa đơn ấy, bạn sẽ đọc được dòng chữ kiểu: nhà làm + trân châu trắng. Cũng được thôi, nhưng mình là dân code đẳng cấp mà, mình muốn cái gì đó kiểu xịn sò hơn, kiểu: "Trà sữa nhà làm và trân châu trắng và hạt thủy tinh". Đấy, như thế mới gọi là bill đẳng cấp. Nhưng làm thể nào để code generate ra được dòng miêu tả xịn như thế được. Đó là lúc ta áp dụng Decorator Pattern.
Đầu tiên ta có 1 cái Interface là Milk Tea bao gồm 2 phương thức là getDescription() và getCost() chẳng hạn.
Tiếp đến ta tạo 2 cái hiện thực cho interface này là HomeMade và Taiwain.
Giờ ta tạo 1 cái interface Topping, nhưng interface này sẽ là kế thừa interface milk tea. Đồng thời tạo 2 cái hiện thực tương ứng là WhiteBubble và GlassesBubble.
Thiết kế sẽ là như thế. Nhưng phải đi vào code, bạn mới hiểu được decorator ở đây là gì. Đầu tiên là interface milk tea và 2 hiện thực homemade, taiwan.
public interface IMilkTea{
    public String getDes();
    public int getCost();
} 

public class HomeMade implements IMilkTea {
    public String getDes() {
        return "tra sua nha lam";
    }
    public int getCost() {
        return 10000;
    }
}

public class Taiwan implements IMilkTea {
    public String getDes() {
        return "tra sua dai loan";
    }
    public int getCost() {
        return 15000;
    }
}
Tiếp đến là interface topping và các hiện thực tương ứng.
public interface Topping extends IMilkTea {
} 

public class WhiteBubble implements Topping {
    private IMilkTea iMilkTea;
    public WhiteBubble (IMilkTea iMilkTea) {
         this.iMilkTea = iMilkTea;
    }
    public String getDes() {
        return iMilkTea.getDes() + " va tran chau trang";
    }
    public int getCost() {
        return iMilkTea.getCost() + 5000;
    }
}

public class GlassesBubble implements Topping {
    private IMilkTea iMilkTea;
    public GlassesBubble (IMilkTea iMilkTea) {
         this.iMilkTea = iMilkTea;
    }
    public String getDes() {
        return iMilkTea.getDes() + " va hat thuy tinh ";
    }
    public int getCost() {
        return iMilkTea.getCost() + 7000;
    }
}
Vậy là xong, bây giờ giả sử khách hàng muốn mua 1 ly trà sữa nhà làm, ta sẽ có đối tượng trà sữa nhà làm và in ra hóa đơn.
HomeMade homeMade = new HomeMade();
System.out.println(homeMade.getDes());
System.out.println(homeMade.getCost());
Nếu khách hàng muốn có topping trân châu trắng, có luôn cho khách.
WhiteBubble whiteBubble = new WhiteBubble(new HomeMade());
System.out.println(whiteBubble.getDes());
System.out.println(whiteBubble.getCost());
Khách đổi ý muốn thêm cả hạt thủy tinh nữa, chơi luôn cho khách.
GlassesBubble glassesBubble = new GlassesBubble (new WhiteBubble(new HomeMade()));
System.out.println(glassesBubble.getDes());
System.out.println(glassesBubble.getCost());
Vậy thôi. Đó chính là Decorator Pattern. Muốn thêm mắm thêm muối gì thì cứ thêm, ko phải sợ. Hê hê
Share:

0 nhận xét:

Đăng nhận xét

Được tạo bởi Blogger.