Bài đăng nổi bật

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 sn phm 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ệ thng sẽ dùng phương thức compareTo() ca 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ệ thng sẽ dùng phương thức compareTo() ca lớp Product đ so sánh các đi tượng sn phm 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

Post a Comment

أحدث أقدم