Design pattern là gì? Tổng quan 3 nhóm pattern và nguyên tắc SOLID

Design pattern là gì? Tổng quan 3 nhóm pattern và nguyên tắc SOLID - Khuê Nguyễn Creator

Trong bài này chúng ta sẽ tìm hiểu design pattern là gì, vì sao lập trình viên nên học, các nhóm pattern chính và nguyên tắc SOLID nằm phía sau chúng. Đây là bài mở đầu chương design pattern của serie C++, 5 bài tiếp theo sẽ đi vào từng pattern cụ thể với code chạy được.

Bài 29 trong Serie Lập trình C++ từ A tới Z

Design pattern là gì?

Design pattern (mẫu thiết kế) là lời giải đã được kiểm chứng cho một vấn đề thiết kế phần mềm hay lặp lại. Nó không phải đoạn code để copy, mà là một cách tổ chức class và đối tượng mà các bạn áp dụng vào bài toán của mình.

Ví dụ đời thường: kiến trúc sư không phát minh lại cầu thang mỗi lần thiết kế nhà. Họ có sẵn những mẫu như cầu thang thẳng, cầu thang xoắn, cầu thang chữ L, mỗi mẫu hợp với một loại nhà. Design pattern là những mẫu như vậy cho phần mềm.

Khái niệm này phổ biến từ cuốn sách Design Patterns: Elements of Reusable Object-Oriented Software (1994) của 4 tác giả Gamma, Helm, Johnson, Vlissides, thường gọi là GoF (Gang of Four). Sách mô tả 23 pattern, tới nay vẫn là tài liệu tham khảo chuẩn.

Vì sao nên học design pattern?

  • Không phát minh lại bánh xe: những vấn đề như “chỉ cần một đối tượng log cho cả chương trình” hay “báo cho nhiều nơi khi dữ liệu thay đổi” đã có lời giải tốt, không cần tự mày mò.
  • Có ngôn ngữ chung với đồng nghiệp: nói “chỗ này dùng Observer” là cả nhóm hiểu ngay cấu trúc, không cần giải thích cả trang.
  • Đọc hiểu thư viện, framework: Qt, Unreal Engine, thư viện của ESP32 dùng pattern khắp nơi. Biết pattern thì đọc code của họ nhanh hơn nhiều.
  • Phỏng vấn: câu hỏi về Singleton, Factory, Observer xuất hiện trong hầu hết các buổi phỏng vấn vị trí C++.

3 nhóm design pattern

Design pattern là gì: sơ đồ 3 nhóm design pattern theo sách GoF: creational, structural, behavioral

Nhóm Giải quyết Pattern học trong serie
Creational (khởi tạo) Tạo đối tượng thế nào cho linh hoạt Singleton, Factory
Structural (cấu trúc) Ghép các class, đối tượng thành cấu trúc lớn hơn (Adapter, Decorator: tham khảo thêm)
Behavioral (hành vi) Các đối tượng giao tiếp, chia trách nhiệm thế nào Observer, Strategy, State

Serie chọn 5 pattern dùng nhiều nhất trong thực tế và gắn với chương trình thư viện quen thuộc, thay vì đi đủ 23 pattern.

Nguyên tắc SOLID

Các pattern đều xoay quanh 5 nguyên tắc thiết kế hướng đối tượng, viết tắt là SOLID:

Nguyên tắc Ý nghĩa Ví dụ trong serie
Single responsibility Mỗi class chỉ làm một việc Sach lưu thông tin sách, không tự in báo cáo hay ghi file
Open/closed Mở để mở rộng, đóng để sửa đổi Thêm loại tài liệu mới bằng class mới, không sửa vòng lặp cũ (bài đa hình)
Liskov substitution Lớp con thay được cho lớp cha mà không sai Ở đâu dùng được TaiLieu& thì truyền Sach vào cũng chạy đúng
Interface segregation Nhiều interface nhỏ tốt hơn một interface lớn Tách CoTheTimKiem, CoTheMuon thay vì một interface làm tất cả
Dependency inversion Phụ thuộc vào interface, không vào class cụ thể nhacTraSach nhận KenhThongBao& chứ không nhận Email (bài trừu tượng)

Không cần học thuộc. Hãy coi chúng như câu hỏi tự kiểm tra khi thiết kế: class này có đang làm quá nhiều việc không? Thêm tính năng mới có phải sửa code cũ không?

Nếu đã đọc các bài tính đa hình và tính trừu tượng trong C++, các bạn đã dùng 2 nguyên tắc O và D mà không để ý. Phần lớn design pattern chính là cách áp dụng có hệ thống những công cụ đó: interface, hàm ảo, đa hình, thành phần.

Lộ trình 5 pattern trong serie

Mỗi bài theo một khung giống nhau: bài toán thực tế trong chương trình thư viện, code chưa dùng pattern và vấn đề của nó, code áp dụng pattern, khi nào nên và không nên dùng.

Bài Pattern Bài toán trong thư viện
30 Singleton Một đối tượng ghi nhật ký dùng chung cho cả chương trình
31 Factory Đọc file dữ liệu, tạo đúng loại sách hay tạp chí theo từng dòng
32 Observer Báo cho các độc giả đang chờ khi cuốn sách được trả
33 Strategy Mỗi loại độc giả một cách tính tiền phạt, đổi được lúc chạy
34 State Cuốn sách chuyển giữa các trạng thái có sẵn, đang mượn, quá hạn

Bài 34 về State pattern có liên hệ trực tiếp với máy trạng thái trong lập trình nhúng, như bài STM32 nút nhấn 3 chế độ.

Khi nào không nên dùng design pattern?

Lưu ý: Pattern là công cụ, không phải mục tiêu. Lỗi hay gặp nhất của người mới học là cố nhét pattern vào mọi chỗ: tạo Factory cho class chỉ có một loại, viết Strategy cho phép tính không bao giờ thay đổi. Code dài gấp ba mà không giải quyết vấn đề gì. Chỉ dùng pattern khi thấy đúng vấn đề mà nó giải quyết.

Một dấu hiệu tốt: viết code đơn giản trước. Khi bắt đầu thấy đau, ví dụ thêm loại tài liệu mới phải sửa 5 chỗ, thì đó là lúc tìm pattern phù hợp để sửa lại thiết kế.

Bài tập

  1. Với mỗi nguyên tắc SOLID, tìm một ví dụ vi phạm trong các chương trình các bạn đã viết, và nêu cách sửa.
  2. Trong một phần mềm quen thuộc (ứng dụng nghe nhạc, game, phần mềm bán hàng), đoán xem chỗ nào có thể đang dùng Singleton, Observer và Strategy.
  3. Đọc lại bài tính trừu tượng: hàm nhacTraSach và interface KenhThongBao đang thể hiện nguyên tắc SOLID nào?

Kết

Design pattern là những lời giải đã được kiểm chứng cho các vấn đề thiết kế lặp đi lặp lại, chia thành 3 nhóm khởi tạo, cấu trúc và hành vi. Học pattern giúp các bạn thiết kế chương trình dễ mở rộng hơn, đọc hiểu framework nhanh hơn, và có ngôn ngữ chung với đồng nghiệp. Nhưng nhớ nguyên tắc quan trọng nhất: chỉ dùng pattern khi có đúng vấn đề nó giải quyết.

Tham khảo thêm danh sách đầy đủ các pattern tại Refactoring.Guru, trang có giải thích và ví dụ C++ cho từng pattern. Bài tiếp theo chúng ta bắt đầu với pattern đơn giản và nổi tiếng nhất: Singleton. Nếu thấy bài viết có ích, hãy chia sẻ cho bạn bè nhé.

Rate this post

Để lại một bình luận

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *