NỘI DUNG BÀI VIẾT
Mô tả chung
Template Method định nghĩa bộ khung của một thuật toán trong một chức năng và chuyển giao một số bước thực hiện thuật toán đó cho các lớp con. Mẫu thiết kế này cho phép lớp con định nghĩa lại các bước nhất định của thuật toán, mà không phải thay đổi cấu trúc thuật toán.
Trong mẫu này, lớp cơ sở (lớp cha) khai báo sẵn thuật toán và lớp dẫn xuất (lớp con) triển khai chi tiết thuật toán.
Ví dụ: Khi chúng ta có một template đã có sẵn header, footer, navigation cho trang web, chỉ riêng phần body là để trống và sẽ hiển thị nội dung theo từng page. Nghĩa là chỉ có phần body là sẽ thay đổi theo từng page, còn các phần khác sẽ giống nhau cho tất cả các page. Trừ một số page đặc biệt mà nội dung của header, footer, navigation sẽ thay đổi.
Khi nào dùng?
Template Method được sử dụng khá nhiều trong mô hình Abstract class (cha) – Concrete Class (con) khi chúng ta muốn các lớp Concrete Class tự thực thi xử lí theo cách của nó, nhưng đồng thời vẫn đảm bảo tuân theo những ràng buộc nhất định từ Abstract class, ví dụ như ràng buộc về thứ tự các bước, hay ràng buộc về đầu vào, đầu ra…
Thành phần Cấu trúc
Mẫu thiết kế này thường gồm các thành phần sau: Một lớp trừu tượng (abstract class) FrameworkClass định nghĩa phương thức templateMethod() gọi lần lượt các phương thức stepOne(), stepTwo() và stepThree(). Phương thức stepTwo() là “hook” method (phương thức chưa được định nghĩa, abstract method). Các lớp kế thừa (ApplicationClassOne, ApplicationClassTwo) sẽ triển khai (định nghĩa) chi tiết phương thức stepTwo() theo cách của nó. Tất cả các phương thức sử dụng lại đều được định nghĩa trong lớp FrameworkClass.
Triển khai
- Chuẩn hóa bộ khung của thuật toán trong một phương thức của lớp cơ sở (template)
- Triển khai cụ thể của các bước riêng lẻ giống nhau được thực hiện trong lớp cơ sở.
- Các bước cần triển khai khác biệt được khai báo (giữ chỗ) trong lớp cơ sở.
- Các lớp kế thừa có thể ghi đè các phương thức “giữ chỗ” trong lớp cơ sở.
- Các lớp kế thừa có thể ghi đè các phương thức đã triển khai trong lớp cơ sở.
- Các lớp kế thừa có thể ghi đè và “gọi ngược lại” các phương thức trong lớp cơ sở.
abstract class Generalization {
// 1. Standardize the skeleton of an algorithm in a “template” method
void findSolution() {
stepOne();
stepTwo();
stepThr();
stepFor();
}
// 2. Common implementations of individual steps are defined in base class
private void stepOne() {
System.out.println(“Generalization.stepOne”);
}
// 3. Steps requiring peculiar implementations are “placeholders” in the base class
abstract void stepTwo();
abstract void stepThr();
void stepFor() {
System.out.println( “Generalization.stepFor” );
}
}
abstract class Specialization extends Generalization {
// 4. Derived classes can override placeholder methods
// 1. Standardize the skeleton of an algorithm in a “template” method
protected void stepThr() {
step3_1();
step3_2();
step3_3();
}
// 2. Common implementations of individual steps are defined in base class
private void step3_1() {
System.out.println(“Specialization.step3_1”);
}
// 3. Steps requiring peculiar implementations are “placeholders” in the base class
abstract protected void step3_2();
private void step3_3() {
System.out.println(“Specialization.step3_3”);
}
}
class Realization extends Specialization {
// 4. Derived classes can override placeholder methods
protected void stepTwo() {
System.out.println(“Realization.stepTwo”);
}
protected void step3_2() {
System.out.println( “Realization.step3_2”);
}
// 5. Derived classes can override implemented methods
// 6. Derived classes can override and “call back to” base class methods
protected void stepFor() {
System.out.println(“Realization.stepFor”);
super.stepFor();
}
}
public class TemplateMethodDemo {
public static void main(String[] args) {
Generalization algorithm = new Realization();
algorithm.findSolution();
}
}
Kết quả:
Generalization.stepOne
Realization.stepTwo
Specialization.step3_1
Realization.step3_2
Specialization.step3_3
Realization.stepFor
Generalization.stepFor
Tham khảo: