Giới thiệu về mẫu thiết kế
Thuộc phần Lập trình hướng đối tượng trong hành trình Java của Coddy. Bài học 64 trên 87.
Mẫu thiết kế là những giải pháp đã được kiểm chứng cho các vấn đề phổ biến mà nhà phát triển thường gặp khi xây dựng phần mềm. Thay vì phải sáng tạo lại từ đầu mỗi lần, bạn có thể áp dụng những khuôn mẫu đã được thử nghiệm qua thời gian này để giải quyết các thử thách thiết kế thường gặp.
Hãy xem mẫu thiết kế (design pattern) như những bản thiết kế. Chúng không cung cấp cho bạn đoạn code hoàn chỉnh để sao chép và dán, mà mô tả cách tổ chức lớp và đối tượng để giải quyết một dạng vấn đề cụ thể. Những mẫu thiết kế bạn sẽ học tận dụng các khái niệm OOP mà bạn đã nắm vững: kế thừa (inheritance), giao diện (interface), đa hình và kết hợp.
Mẫu thiết kế được chia thành ba nhóm chính:
| Nhóm | Mục đích | Ví dụ |
|---|---|---|
| Khởi tạo | Cách tạo đối tượng | Singleton, Factory, Builder |
| Cấu trúc | Cách kết hợp các đối tượng | Adapter, Decorator, Composite |
| Hành vi | Cách các đối tượng giao tiếp | Observer, Strategy, Command |
Tại sao nên học mẫu thiết kế? Chúng giúp bạn có chung vốn từ vựng với các nhà phát triển khác: nói “dùng Factory ở đây” sẽ truyền đạt ngay một ý tưởng phức tạp. Chúng cũng giúp bạn viết code linh hoạt, dễ bảo trì hơn bằng cách áp dụng các nguyên tắc như “lập trình hướng đến giao diện, không phải cách triển khai”.
Trong các bài học sắp tới, bạn sẽ triển khai một số mẫu thiết kế thiết yếu, bắt đầu với các mẫu thiết kế khởi tạo (creational patterns) như Singleton và Factory, sau đó chuyển sang các mẫu thiết kế hành vi (behavioral patterns) như Observer và Strategy.
Thử thách
DễHãy tạo một trình phân loại mẫu thiết kế đơn giản để thể hiện bạn hiểu ba nhóm mẫu thiết kế! Bạn sẽ tạo một hệ thống phân loại các mẫu thiết kế và giải thích mục đích của chúng, đồng thời sắp xếp code trong nhiều tệp.
Bạn sẽ tạo ba tệp:
Pattern.java: Tạo một giao diện có tênPattern, định nghĩa hợp đồng cho mọi mẫu thiết kế. Giao diện của bạn cần khai báo hai phương thức:String getCategory()trả về nhóm của mẫu thiết kế (Creational, Structural hoặc Behavioral), vàString getPurpose()trả về mô tả chức năng của nhóm mẫu thiết kế đó.PatternInfo.java: Tạo ba lớp triển khai giao diệnPattern, mỗi lớp đại diện cho một nhóm mẫu thiết kế:CreationalPatternsẽ trả về"Creational"cho nhóm và"How objects are created"cho mục đích.StructuralPatternsẽ trả về"Structural"cho nhóm và"How objects are composed"cho mục đích.BehavioralPatternsẽ trả về"Behavioral"cho nhóm và"How objects communicate"cho mục đích.Main.java: Kết hợp các phần để tạo trình phân loại mẫu thiết kế! Bạn sẽ nhận một đầu vào: tên mẫu thiết kế (String), có thể là"Singleton","Factory","Adapter","Decorator","Observer"hoặc"Strategy".Dựa trên đầu vào, hãy tạo đối tượng mẫu thiết kế phù hợp:
"Singleton"và"Factory"là các mẫu thiết kế Creational"Adapter"và"Decorator"là các mẫu thiết kế Structural"Observer"và"Strategy"là các mẫu thiết kế Behavioral
Lưu đối tượng mẫu thiết kế vào một biến có kiểu
Pattern(giao diện), qua đó thể hiện nguyên tắc lập trình dựa trên giao diện. Sau đó, in ra ba dòng sau:Pattern: [input pattern name]Category: [category from getCategory()]Purpose: [purpose from getPurpose()]
Bạn sẽ nhận một đầu vào: tên của một mẫu thiết kế (String).
Thử thách này giúp củng cố ý chính của bài học: các mẫu thiết kế được sắp xếp thành các nhóm dựa trên vấn đề mà chúng giải quyết. Khi dùng giao diện, bạn cũng thực hành nguyên tắc "lập trình dựa trên giao diện, không phải dựa trên cách triển khai", một khái niệm cốt lõi giúp các mẫu thiết kế phát huy sức mạnh!
Tự làm thử
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String patternName = scanner.nextLine();
// TODO: Khai báo một biến kiểu Pattern (giao diện)
Pattern pattern = null;
// TODO: Dựa vào patternName, tạo đối tượng mẫu thiết kế phù hợp:
// - "Singleton" và "Factory" là các mẫu khởi tạo
// - "Adapter" và "Decorator" là các mẫu cấu trúc
// - "Observer" và "Strategy" là các mẫu hành vi
// TODO: In đầu ra theo định dạng sau:
// Pattern: [tên mẫu thiết kế từ đầu vào]
// Category: [danh mục từ getCategory()]
// Purpose: [mục đích từ getPurpose()]
}
}
Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.
Tất cả bài học trong Lập trình hướng đối tượng
1Kiến thức cơ bản về lập trình hướng đối tượng
Tệp bên ngoàiGiới thiệu về lập trình hướng đối tượngLớp và đối tượngTừ khóa thisPhương thứcTrường (thuộc tính)Phương thức khởi tạoNạp chồng phương thức khởi tạoÔn tập: Máy tính đơn giản4Kế thừa
Kế thừa cơ bản (extends)Từ khóa superGhi đè phương thức (@Override)Chuỗi gọi hàm khởi tạoLớp ObjectKế thừa đơn và đa cấpVì sao không hỗ trợ kế thừa nhiều lớpÔn tập: Phân cấp lớp Employee7Phương thức đặc biệt và lớp Object
Phương thức toString()equals() và hashCode()Phương thức clone()compareTo() và ComparableGiao diện ComparatorÔn tập: sắp xếp tùy chỉnh2Bộ điều chỉnh quyền truy cập và đóng gói
Tổng quan về các mức truy cậpPhương thức getter và setterẨn thông tinTừ khóa finalÔn tập: Trình quản lý tài khoản ngân hàng5Tính đa hình
Kiến thức cơ bản về nạp chồng phương thứcGhi đè phương thức (thời gian chạy)Chuyển kiểu lên và chuyển kiểu xuốngToán tử instanceofLớp và phương thức trừu tượngÔn tập: máy tính hình học8Khái niệm OOP nâng cao
Kết hợp và kế thừaKết tập và hợp thànhLớp bên trong, lớp lồng nhau và lớp ẩn danhKiểu enum và phương thức enumBản ghi (Java 16+)Lớp sealed (Java 17+)11Mẫu thiết kế phần 1
Giới thiệu về mẫu thiết kếMẫu SingletonMẫu FactoryMẫu BuilderMẫu ObserverMẫu Strategy3Thuộc tính lớp và thành viên tĩnh
Biến của instance và biến tĩnhPhương thức tĩnhKhối tĩnhHằng số (static final)Ôn tập: bộ đếm và tiện ích6Giao diện và lớp trừu tượng
Giới thiệu về giao diệnTriển khai giao diệnTriển khai nhiều giao diệnPhương thức mặc định và tĩnh trong giao diệnLớp trừu tượng và giao diệnGiao diện hàmÔn tập: hệ thống thanh toán9Kiểu tổng quát
Giới thiệu về kiểu tổng quátLớp tổng quátPhương thức tổng quátTham số kiểu có giới hạnKý tự đại diện (?, extends, super)Ôn tập: vùng chứa tổng quát12Mẫu thiết kế, phần 2
Mẫu CommandMẫu AdapterMẫu DecoratorMẫu Template MethodMẫu StateMẫu CompositeMẫu IteratorTự luyện tập: Trình biên dịch Java online