Strategy là một trong số rất nhiều các mẫu thiết kế dành cho
phát triển ứng dụng với OOP. Đây
là pattern cho phép các giải thuật khác nhau có thể được lựa chọn trong thời-gian-chạy
(run-time). Hay nói cách khác, Strategy định nghĩa một họ các giải thuật khác
nhau, mỗi giải thuật được triển khai bởi một lớp (class) cụ thể và chúng có thể
hoán đổi cho nhau tùy vào ngữ cảnh. Strategy giúp các giải thuật khác nhau độc
lập với client sử dụng nó.
Ví dụ, một lớp thực hiện nhiệm vụ so sánh dữ liệu đầu
vào có thể sử dụng mẫu thiết kế Strategy để tự động lựa chọn giải thuật cho việc
này dựa trên loại dữ liệu, nguồn gốc của chúng, lựa chọn của người dùng hay các
yếu tố khác. Những yếu tố này không được biết cho tới thời-gian-chạy (runtime)
và khi đó tùy vào loại dữ liệu mà hệ thống lựa chọn cách thức so sánh khác
nhau. Các giải pháp so sánh được đóng gói trong các đối tượng riêng biệt sẽ được
sử dụng bởi những đối tượng thực hiện việc này tại các phân vùng khác nhau của
hệ thống (hoặc thậm chí ở những hệ thống khác nhau) mà không gây ra sự trùng lặp
về mã lệnh.
Strategy thường được biểu diễn bằng UML
như sau:
Ví dụ dưới đây sử dụng Java để minh họa
cụ thể về Strategy.
1. Sử dụng
Interface có sẵn trong Java đó là java.lang.Comparable, interface này có
phương thức compareTo() cho phép các lớp triển khai nó thực hiện việc so sánh
hai đối tượng với nhau.
2. Triển khai 2 lớp kế thừa Comparable,
lớp Student thể hiện các đối tượng sinh viên, Product thể hiện các đối tượng sản
phẩm.
Hai lớp này sẽ cài đặt phương thức
compareTo() để so sánh các đối tượng Sinh viên với nhau hoặc các đối tượng Sản
phẩm với nhau. Khi đó ta có sơ đồ quan hệ giữa các lớp và interface như sau:
Sau đây chúng ta cùng quan sát mã nguồn
của 2 lớp này:
Lớp Student:
public class Student implements
Comparable<Student> {
private String rollNo;
private String fullName;
private double marks;
public Student(String
rollNo, String fullName, double marks) {
this.rollNo = rollNo;
this.fullName
= fullName;
this.marks = marks;
}
/* Hai sinh viên so sánh với
nhau theo tên (fullName) */
@Override
public int compareTo(Student
o) {
if (o == null || o.fullName
== null) {
return 1;
}
if (this.fullName==null) {
return -1;
}
return this.fullName.compareTo(o.fullName);
}
@Override
public String
toString() {
return rollNo + " -
" + fullName;
}
}
Các giá trị trả về tùy thuộc vào đối tượng
sinh viên kia hoặc tuy thuộc vào việc so sánh hai thuộc tính fullName của 2 đối
tượng sinh viên.
Lớp Product:
public class Product implements Comparable<Product> {
private String serial;
private String productName;
private double price;
public Product(String serial, String productName, double price) {
this.serial = serial;
this.productName = productName;
this.price = price;
}
/* Hai sản phẩm so sánh với nhau theo giá bán */
@Override
public int compareTo(Product o) {
if (o == null || this.price > o.price) {
return 1;
}
if (this.price < o.price) {
return -1;
}
return 0;
}
@Override
public String toString() {
return serial + " - " + productName;
}
}
Các giá trị trả về tùy thuộc vào đối tượng
sản phẩm kia hoặc tùy thuộc vào việc so sánh hai thuộc tính price của 2 sản phẩm
với nhau.
3. Chương trình minh họa
Chương trình dưới đây thể hiện việc so
sánh giữa các đội tượng sinh viên với nhau và giữa các sản phẩm với nhau. Trong
phương thức compare(), Collections (đóng vai trò của lớp Context trong hình vẽ
UML mô tả Strategy ở trên) cài đặt phương thức sort() tự xác định loại đối tượng
và sử dụng phương thức compareTo() cho phù hợp.
public class Client {
public static void compare(ArrayList list) {
if (list != null && list.size() > 0) {
Collections.sort(list);
for (Object obj : list) {
System.out.println(" + " + obj);
}
}
}
public static void main(String[] args) {
ArrayList<Student> students = new ArrayList<Student>();
students.add(new Student("A01234", "Minh Le Hoang", 12.5));
students.add(new Student("A01235", "An Nguyen Van", 15.5));
students.add(new Student("A01235", "Tuan Nguyen Anh", 13.5));
students.add(new Student("A01235", "Ha Le Hoang", 17.5));
System.out.println("Sap xep sinh vien: ");
//Hệ thống sẽ dùng phương thức compareTo() của lớp Student để so sánh các đối tượng Sinh viên:
Client.compare(students);
ArrayList<Product> products = new ArrayList<Product>();
products.add(new Product("P0023", "Dell Vostro 3400", 1200));
products.add(new Product("P0012", "IBM Thinpad T60", 1100));
products.add(new Product("P0003", "Vaio Z", 3000));
products.add(new Product("P0303", "HP Pavilon", 1230));
System.out.println("Sap xep san pham: ");
//Hệ thống sẽ dùng phương thức compareTo() của lớp Product để so sánh các đối tượng sản phẩm với nhau:
Client.compare(products);
}
}
Qua VD đơn giản này chắc bạn đã phần
nào hiểu được về Strategy Pattern và sự hiện diện của nó trong các thiết kế sẵn
có của Java như bạn đã thấy trong Comparable.
Tạp chí lập trình
إرسال تعليق