Giới thiệu
Mẫu thiết kế là một phương pháp cổ điển để giải quyết những vấn đề lặp đi lặp lại trong thiết kế phần mềm. Trong bài viết này, chúng ta sẽ tìm hiểu về Mẫu Chiến Lược (Strategy Pattern) - được viết bằng Clprolf, một ngôn ngữ cho phép các vai trò và hợp đồng hướng đối tượng trở nên rõ ràng hơn.
Người đọc không cần lo ngại nếu chưa quen với Clprolf:
- Tình huống sử dụng là điều quen thuộc,
- Giải pháp là mẫu thiết kế mà bạn đã biết,
- Và bạn sẽ thấy Clprolf làm rõ cả hai mặt của vấn đề.
Vấn đề 🤔
Bạn có một hành vi cần dễ dàng thay thế (tại thời điểm chạy hoặc cấu hình). Ví dụ: áp dụng các chính sách giảm giá khác nhau mà không cần thay đổi mã thanh toán.
Giải pháp Clprolf ✅
Trong Clprolf:
- Một chiến lược được mô hình hóa như một
version_inh abstraction(một quy tắc đơn giản, dễ thay thế), - Mỗi chiến lược cụ thể cũng là một
abstractionmà hợp đồng với chiến lược cơ bản, - Ngữ cảnh khai báo sự phụ thuộc của nó với
with_compat.
Kết quả: vai trò, triển khai và sự phụ thuộc của chiến lược trở nên rõ ràng.
Ví dụ: Các chiến lược giảm giá 📝
Chúng ta sẽ định nghĩa một Discount và hai triển khai:
NoDiscount(không làm gì)PercentageDiscount(ví dụ, giảm 15%)
Sau đó là ngữ cảnh Checkout sử dụng bất kỳ giảm giá nào được cung cấp cho nó.
Mã Clprolf
java
// 1) Hợp đồng chiến lược (một quy tắc chung cho giảm giá)
public version_inh abstraction Discount {
int apply(int price);
}
// 2) Các chiến lược cụ thể
public abstraction NoDiscount contracts Discount {
public int apply(int price) { return price; }
}
public abstraction PercentageDiscount contracts Discount {
private int percent;
public PercentageDiscount(int percent) { this.percent = percent; }
public int apply(int price) {
return price - (price * percent / 100);
}
}
// 3) Ngữ cảnh phụ thuộc vào một chiến lược
public agent Checkout {
private with_compat Discount strategy;
public Checkout(with_compat Discount strategy) {
this.strategy = strategy;
}
public int total(int[] prices) {
int sum = 0;
for (int p : prices) sum += p;
return strategy.apply(sum);
}
}
Demo: Giảm giá có thể thay thế 👀
java
public worker_agent StrategyDemo {
public static void main(String[] args) {
int[] cart = new int[] { 4000, 2000, 1500 }; // tổng = 7500
// Không có giảm giá
with_compat Discount none = new NoDiscount();
Checkout checkoutNone = new Checkout(none);
System.out.println(checkoutNone.total(cart)); // 7500
// Giảm 15%
with_compat Discount promo15 = new PercentageDiscount(15);
Checkout checkout15 = new Checkout(promo15);
System.out.println(checkout15.total(cart)); // 6375
}
}
Tại sao điều này rõ ràng trong Clprolf 🔎
version_inh abstractioncho thấy ngay lập tức rằng một giảm giá là một quy tắc có thể thay thế, không phải là một tác nhân trung tâm.contractskhiến mỗi giảm giá cụ thể trở thành một triển khai thực sự của quy tắc đó.with_compatkhai báo sự phụ thuộc một cách trực tiếp: quá trình thanh toán mong đợi “một giảm giá,” không có sự kết nối ẩn.- Việc thay thế chỉ đơn giản là cung cấp một abstraction khác — ngữ cảnh không bị thay đổi.
Kết luận 🎯
Trong Clprolf, Mẫu Chiến Lược không phải là một thủ thuật - nó đơn giản là:
Khai báo một quy tắc (
abstraction), cung cấp các triển khai và thay thế chúng bằngwith_compat.
Hành vi trở nên có thể thay thế và ý định trở nên rõ ràng trong cú pháp.
Lưu ý Đổi mới 💡: Các mẫu tiết lộ vai trò
Trong lập trình hướng đối tượng truyền thống, Mẫu Chiến Lược thường được thể hiện như một cấu trúc kỹ thuật thuần túy. Nhưng trên thực tế, nó đã mang theo một vai trò kinh doanh: “chọn một hành vi.”
👉 Clprolf làm rõ khía cạnh này.
- Ở đây, vai trò là
abstraction→ một giảm giá là một quy tắc, không phải là một tác nhân. - Trong một trường hợp khác, một Chiến Lược có thể là một
agent(ví dụ, chọn một thuật toán định tuyến). - Đối với các biến thể kỹ thuật, nó có thể là một
worker_agent(như nhiều triển khai DAO).
Đây là nơi Clprolf đổi mới:
Các mẫu thiết kế không chỉ giải quyết vấn đề - mà chúng tự nhiên ánh xạ đến các vai trò (
agent,abstraction,worker_agent). Và khi vai trò được làm rõ, ý định của mẫu trở nên rõ ràng như pha lê.
✨ Đó là tất cả - tình huống quen thuộc, giải pháp rõ ràng và một sự đổi mới: các vai trò biến các mẫu thành những thiết kế tự giải thích.