/ / Mẫu thiết kế trang trí là gì?

Mẫu thiết kế trang trí là gì?

Một trong những nguyên tắc quan trọng nhất trong phát triển phần mềm là nguyên tắc thiết kế đóng mở. Nguyên tắc thiết kế này nhấn mạnh rằng các lớp nên mở để mở rộng, nhưng đóng để sửa đổi. Mẫu thiết kế trang trí thể hiện nguyên tắc thiết kế đóng mở.


Với mẫu thiết kế trang trí, bạn có thể dễ dàng mở rộng một lớp bằng cách cung cấp cho nó hành vi mới mà không cần thay đổi mã hiện có của nó. Mẫu trang trí thực hiện điều này một cách linh hoạt trong thời gian chạy, sử dụng thành phần. Mẫu thiết kế này được biết đến như một giải pháp thay thế linh hoạt cho việc sử dụng tính kế thừa để mở rộng hành vi.


Mẫu thiết kế trang trí hoạt động như thế nào?

Mặc dù mẫu trang trí là một thay thế cho kế thừa lớp, nhưng nó kết hợp một số khía cạnh kế thừa trong thiết kế của nó. Một khía cạnh quan trọng của mẫu trang trí là tất cả các lớp của nó đều có liên quan trực tiếp hoặc gián tiếp.

Một mẫu thiết kế trang trí điển hình có cấu trúc sau:

Cấu trúc mẫu trang trí

Từ sơ đồ lớp ở trên, bạn có thể thấy rằng mẫu trang trí có bốn lớp chính.

Thành phần: đây là một lớp trừu tượng (hoặc giao diện), đóng vai trò là siêu kiểu cho mẫu trang trí.

Thành phần bê tông: đây là những đối tượng mà bạn có thể trang trí với các hành vi khác nhau trong thời gian chạy. Chúng kế thừa từ giao diện thành phần và thực hiện các chức năng trừu tượng của nó.

Người trang trí: lớp này là trừu tượng và có cùng siêu kiểu với đối tượng mà nó sẽ trang trí. Trong sơ đồ lớp, bạn sẽ thấy hai mối quan hệ giữa các lớp thành phần và lớp trang trí. Mối quan hệ đầu tiên là mối quan hệ thừa kế; mỗi người trang trí là một thành phần. Mối quan hệ thứ hai là một trong những thành phần; mỗi người trang trí có một (hoặc kết thúc tốt đẹp một) thành phần.

Trang trí bê tông: đây là những bộ trang trí riêng lẻ cung cấp cho một thành phần một hành vi cụ thể. Bạn nên lưu ý rằng mỗi trình trang trí cụ thể có một biến thể hiện chứa tham chiếu đến một thành phần.

Triển khai Mẫu thiết kế trang trí trong Java

Một ứng dụng đặt bánh pizza mẫu có thể chứng minh đầy đủ cách sử dụng mẫu trang trí để phát triển ứng dụng. Ứng dụng pizza mẫu này cho phép khách hàng đặt pizza với nhiều loại toppings. Lớp đầu tiên của mẫu trang trí là giao diện bánh pizza:

 public interface Pizza {
    public abstract String description();
    public abstract double cost();
}

Giao diện Pizza là lớp thành phần. Vì vậy, bạn có thể tạo một hoặc nhiều lớp cụ thể từ nó. Công ty pizza sản xuất hai loại pizza chính, dựa trên loại bột của họ. Một loại bánh pizza có bột men:

 public class YeastCrustPizza implements Pizza {
    @Override
    public String description() {
        return "Pizza dough made with yeast";
    }

    @Override
    public double cost() {
        return 18.00;
    }
}

YeastCrustPizza là lớp Java cụ thể đầu tiên của giao diện Pizza. Loại bánh pizza khác có sẵn là bánh mì dẹt:

 public class FlatbreadCrustPizza implements Pizza {
    @Override
    public String description() {
        return "Pizza dough made with flatbread";
    }

    @Override
    public double cost() {
        return 15.00;
    }
}

Lớp FlatbreadCrustPizza là thành phần cụ thể thứ hai và giống như lớp YeastCrustPizza, nó thực hiện tất cả các chức năng trừu tượng của giao diện Pizza.

người trang trí

Lớp trang trí luôn trừu tượng, vì vậy bạn không thể tạo một thể hiện mới trực tiếp từ nó. Nhưng cần phải thiết lập mối quan hệ giữa những người trang trí khác nhau và các thành phần mà họ sẽ trang trí.

 public abstract class ToppingDecorator implements Pizza {
    public String description() {
        return "Unknown Topping";
    }
}

Lớp ToppingDecorator đại diện cho lớp trang trí trong ứng dụng mẫu này. Giờ đây, công ty bánh pizza có thể tạo ra nhiều loại toppings (hoặc trang trí) khác nhau, bằng cách sử dụng lớp ToppingDecorator. Giả sử một chiếc bánh pizza có thể có ba loại nhân khác nhau, đó là pho mát, xúc xích cay và nấm.

Topping phô mai

 public class Cheese extends ToppingDecorator {
    private Pizza pizza;

    public Cheese(Pizza pizza) {
        this.pizza = pizza;
    }

    @Override
    public String description() {
        return pizza.description() + ", Cheese Topping";
    }

    @Override
    public double cost() {
        return pizza.cost() + 2.50;
    }
}

Pepperoni Topping

 public class Pepperoni extends ToppingDecorator {
    private Pizza pizza;

    public Pepperoni(Pizza pizza) {
        this.pizza = pizza;
    }

    @Override
    public String description() {
        return pizza.description() + ", Pepperoni Topping";
    }

    @Override
    public double cost() {
        return pizza.cost() + 3.50;
    }
}

Topping nấm

 public class Mushroom extends ToppingDecorator {
    private Pizza pizza;

    public Mushroom(Pizza pizza) {
        this.pizza = pizza;
    }

    @Override
    public String description() {
        return pizza.description() + ", Mushroom Topping";
    }

    @Override
    public double cost() {
        return pizza.cost() + 4.50;
    }
}

Bây giờ bạn có một ứng dụng đơn giản được triển khai bằng cách sử dụng mẫu thiết kế trang trí. Nếu một khách hàng đặt một chiếc bánh pizza đế men với pho mát và xúc xích tiêu, thì mã thử nghiệm cho trường hợp đó sẽ như sau:

 public class Main {
    public static void main(String[] args) {
        Pizza pizza1 = new YeastCrustPizza();
        pizza1 = new Pepperoni(pizza1);
        pizza1 = new Cheese(pizza1);
        System.out.println(pizza1.description() + " $" + pizza1.cost());
    }
}

Chạy mã này sẽ tạo ra đầu ra sau trong bảng điều khiển:

Hoa văn trang trí pizza1

Như bạn có thể thấy, đầu ra cho biết loại bánh pizza cùng với tổng chi phí của nó. Chiếc bánh pizza ban đầu là một chiếc bánh pizza có vỏ men với giá $18,00, nhưng với mẫu trang trí, ứng dụng có thể thêm các tính năng mới và giá phù hợp của chúng vào bánh pizza. Do đó, tạo cho bánh pizza hành vi mới mà không làm thay đổi mã hiện có (bánh pizza vỏ men).

Với mẫu trang trí, bạn cũng có thể áp dụng hành vi tương tự cho một đối tượng bao nhiêu lần tùy thích. Nếu một khách hàng đặt một chiếc bánh pizza với mọi thứ trên đó và thêm một ít phô mai, bạn có thể cập nhật lớp chính bằng mã sau để phản ánh điều này:

 Pizza pizza2 = new YeastCrustPizza();
pizza2 = new Pepperoni(pizza2);
pizza2 = new Cheese(pizza2);
pizza2 = new Cheese(pizza2);
pizza2 = new Mushroom(pizza2);

System.out.println(pizza2.description() + " $" + pizza2.cost());

Ứng dụng được cập nhật sẽ tạo đầu ra sau trong bảng điều khiển:

Mẫu trang trí pizza2

Ưu điểm của việc sử dụng Mẫu thiết kế trang trí

Hai ưu điểm chính của việc sử dụng mẫu thiết kế trang trí là tính bảo mật và tính linh hoạt. Mẫu trang trí cho phép bạn phát triển mã an toàn hơn bằng cách không can thiệp vào mã bảo mật có sẵn. Thay vào đó, nó mở rộng mã hiện có thông qua thành phần. Ngăn chặn hiệu quả sự xuất hiện của các lỗi mới hoặc các tác dụng phụ ngoài ý muốn.

Do thành phần, nhà phát triển cũng có rất nhiều tính linh hoạt khi sử dụng mẫu trang trí. Bạn có thể triển khai trình trang trí mới bất kỳ lúc nào để thêm hành vi mới mà không làm thay đổi mã hiện có và làm gián đoạn ứng dụng.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *