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 PHP của Coddy. Bài học 70 trên 91.
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 phát minh lại từ đầu mỗi lần, bạn có thể áp dụng những khuôn mẫu đã được thiết lập này để giải quyết các thử thách tương tự trong đoạn code của mình.
Hãy xem các mẫu thiết kế như những công thức nấu ăn. Cũng như đầu bếp làm theo công thức để tạo ra món ăn đã được hoàn thiện qua thời gian, lập trình viên dùng các mẫu thiết kế để cấu trúc đoạn code theo những cách mà vô số lập trình viên trước đó đã thử nghiệm và tinh chỉnh.
Các mẫu thiết kế thường được chia thành ba nhóm:
| Danh mục | Mục đích | Ví dụ |
|---|---|---|
| Khởi tạo | Cách tạo đối tượng | Singleton, Factory |
| Cấu trúc | Cách kết hợp các đối tượng | Adapter, Decorator |
| Hành vi | Cách các đối tượng giao tiếp | Observer, Strategy |
Thực ra, bạn đã sử dụng các mẫu thiết kế trong suốt khóa học này mà không nhận ra. Khi tạo các lớp trừu tượng có phương thức mà các lớp con phải triển khai, bạn đã áp dụng một dạng của mẫu Template Method. Khi dùng các giao diện để định nghĩa hợp đồng, bạn đã chuẩn bị cho mẫu Strategy.
Học các mẫu thiết kế giúp bạn có chung vốn từ vựng với những nhà phát triển khác. Thay vì giải thích chi tiết một cấu trúc phức tạp, bạn chỉ cần nói “Mình đã dùng mẫu Factory ở đây”, các nhà phát triển giàu kinh nghiệm sẽ hiểu ngay cách tiếp cận của bạn. Trong các bài học tiếp theo, chúng ta sẽ triển khai một số mẫu thiết kế thiết yếu trong PHP.
Thử thách
DễHãy xây dựng một hệ thống định dạng thông điệp đơn giản để minh họa cách các mẫu thiết kế giúp sắp xếp code. Bạn sẽ xác định mỗi thành phần thuộc nhóm mẫu nào và tìm hiểu cách các phần khác nhau của một hệ thống phối hợp với nhau.
Bạn sẽ sắp xếp code trong ba tệp:
MessageFormatter.php: Tạo một giao diện (interface) có tênMessageFormatter, định nghĩa quy ước định dạng thông điệp. Giao diện này cần có một phương thức duy nhất làformat(string $message): string. Đây là nhóm hành vi. Nhóm này định nghĩa cách các đối tượng giao tiếp và xử lý dữ liệu.Formatters.php: Bao gồm tệp MessageFormatter và tạo hai lớp triển khai giao diện:UppercaseFormatter: Phương thứcformat()của lớp này trả về thông điệp đã chuyển thành chữ in hoaBracketFormatter: Phương thứcformat()của lớp này đặt thông điệp trong dấu ngoặc vuông như[message]
main.php: Bao gồm tệp Formatters. Bạn sẽ nhận hai đầu vào: một chuỗi thông điệp và một kiểu định dạng ("upper"hoặc"bracket").Tạo một hàm có tên
processMessage, nhận mộtMessageFormattervà một chuỗi thông điệp, sau đó trả về kết quả đã định dạng. Hàm này không cần biết cụ thể nó nhận được bộ định dạng nào. Hàm chỉ gọiformat()trên đối tượng được truyền vào.Dựa trên đầu vào về kiểu định dạng, hãy tạo đối tượng bộ định dạng phù hợp. Truyền đối tượng đó cùng với thông điệp vào hàm
processMessage, rồi in kết quả.Trên dòng mới, hãy in nhóm mẫu mà cấu trúc này đại diện. Vì chúng ta định nghĩa các hành vi có thể thay thế cho nhau thông qua một giao diện, hãy in:
Pattern category: Behavioral
Thử thách này cho thấy giao diện cho phép bạn thay thế các cách triển khai mà không cần thay đổi code sử dụng chúng. Đây là nền tảng cho các mẫu như Strategy mà bạn sẽ tìm hiểu trong những bài học sắp tới.
Tự làm thử
<?php
require_once 'Formatters.php';
// Đọc đầu vào (input)
$message = trim(fgets(STDIN));
$formatterType = trim(fgets(STDIN));
// TODO: Tạo hàm (function) processMessage nhận một MessageFormatter
// và một chuỗi (string) thông điệp, rồi trả về kết quả đã định dạng
// TODO: Dựa vào $formatterType ("upper" hoặc "bracket"), tạo bộ định dạng phù hợp
// TODO: Gọi processMessage với bộ định dạng và thông điệp, rồi in ra (print) kết quả
// TODO: In loại mẫu trên một dòng mới
// Định dạng: "Pattern category: Behavioral"
?>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
1Nền tảng về OOP
Tệp bên ngoàiGiới thiệu về OOPLớp và đối tượngTừ khóa $thisPhương thứcThuộc tínhHàm khởi tạo (__construct)Hàm hủy (__destruct)Ôn tập: máy tính đơn giản4Kế thừa
Kế thừa cơ bảnTừ khóa parent::Ghi đè phương thứcTừ khóa finalLớp trừu tượngÔn tập: hệ thống phân cấp nhân viên7Đóng gói
Công khai, được bảo vệ, riêng tưTìm hiểu sâu về bộ điều chỉnh quyền truy cậpGetter và setterẨn thông tinRút gọn hàm khởi tạo (8.0)Ôn tập: hệ thống hồ sơ học sinh2Không gian tên và tự động nạp
Giới thiệu về không gian tênTừ khóa useChuẩn tự động nạp PSR-4Trình tự động nạp của ComposerÔn tập: dự án có tổ chức5Giao diện và hợp đồng
Giới thiệu về giao diệnTriển khai giao diệnTriển khai nhiều giao diệnGiao diện và lớp trừu tượngGợi ý kiểu với giao diệnÔn tập: Máy tính hình học8Phương thức ma thuật
Giới thiệu về phương thức ma thuật__toString và __debugInfo__get, __set, __isset, __unset__call và __callStatic__clone và sao chép đối tượng__serialize và __unserializeÔn tập: Bộ sưu tập tùy chỉnh3Thuộc tính của lớp
Thuộc tính instance và staticHằng số trong lớpPhương thức và thuộc tính staticThuộc tính private và protectedThuộc tính chỉ đọc (PHP 8.1)Ôn tập: Trình quản lý tài khoản ngân hàng6Đa hình
Xem lại việc ghi đè phương thứcĐa hình qua giao diệnGợi ý kiểu và kiểu hợpLiên kết tĩnh muộnÔn tập: bộ xử lý thanh toánTự luyện tập: Trình biên dịch PHP online