Design Pattern - Part I: Introduction
I. Design pattern là gì? Phân tích và thiết kế là những việc đầu tiên cần phải làm khi bắt tay vào sản xuất phần mềm. Một thiết kế tốt sẽ giúp chúng ta tránh phải chỉnh sửa nhiều lần. Một người thiết kế hướng đối tượng có kinh nghiệm thường nói rằng rất khó để cho ra một thiết kế chuẩn ngay từ ...
I. Design pattern là gì?
Phân tích và thiết kế là những việc đầu tiên cần phải làm khi bắt tay vào sản xuất phần mềm. Một thiết kế tốt sẽ giúp chúng ta tránh phải chỉnh sửa nhiều lần. Một người thiết kế hướng đối tượng có kinh nghiệm thường nói rằng rất khó để cho ra một thiết kế chuẩn ngay từ lần đầu, mà nó thường phải trải quả nhiều lần tái sử dụng và chỉnh sửa sau mỗi lần. Nếu nhớ được chi tiết về vấn đề trước đây và cách giải quyết nó, chúng ta có thể tái sử dụng thay vì phải sáng tạo lại. He he, nhưng đấy là trong trường hợp bạn nhớ, giả sử chúng ta không nhớ rõ thì sao, lục lại tài liệu, tìm giải pháp mới,... Đó chính là lý do design pattern ra đời, nhiệm vụ của nó chỉ đơn giản là cô đọng lại giải pháp (đương nhiên phải là giải pháp hiệu quả) để giải quyết một vấn đề cụ thể thành một mẫu thiết kế có thể tái sử dụng.
Tạm thời chúng ta dừng lại ở việc hiểu xuất xứ của design pattern. Còn đây là định nghĩa của nó:
"Mỗi pattern mô tả một vấn đề xảy ra lặp đi lặp lại, và trình bày trọng tâm của giải pháp cho vấn đề đó, theo cách mà bạn có thể dùng đi dùng lại hàng triệu lần mà không cần phải suy nghĩ."
Thực ra đây là định nghĩa của Christopher Alexander dành cho pattern trong ngành kiến trúc, nhưng những gì ông nói cũng chính xác về mẫu thiết kế hướng đối tượng.
Về tổng quan chung, một pattern có 4 thành phần chính:
- Tên: được dùng để mô tả vấn đề thiết kế, giải pháp, và kết quả trong từ 1 đến 2 chữ.
- Vấn đề mà pattern này được áp dụng.
- Giải pháp: mô tả những thành phần tạo nên thiết kế, mối quan hệ, trách nhiệm và cộng tác giữa các thành phần đó
- Cuối cùng là hệ quả, là lợi ích cũng như hạn chế khi sử dụng pattern. Mặc dù những điều này không được nhắc đến khi chúng ta ra quyết định thiết kế, nhưng rõ ràng việc đánh giá và hiểu được chi phí cũng như lợi ích khi áp dụng pattern là cần thiết.
Một điều quan trọng nữa là design pattern là những thiết kế ở cấp độ class (tức là lớp và đối tượng), sau series này mình sẽ tìm hiểu và trình bày về những pattern ở mức độ kiến trúc của hệ thống (archiectural pattern), còn hiện tại mình đang tìm hiểu về design pattern nên tiện thể trình bày luôn ở đây. =))
II. Phân loại Design Pattern
Trong cuốn Design Pattern kinh điển của Gang of Four có liệt kê 23 design pattern, tác giả chia chúng thành 3 loại, bao gồm creational pattern, structural pattern và behavioral pattern
Creational Patterns
Những pattern thuộc nhóm này trừu tượng hóa quá trình khởi tạo. Chúng giúp việc tạo và trình diễn đối tượng độc lập với hệ thống. Nhóm này bao gồm 5 design pattern, cụ thể là:
Tên | Mục đích |
---|---|
Abstract Factory | Cung cấp một interface cho việc tạo lập các đối tượng mà không cần xác định lớp cụ thể tạo mỗi đối tượng |
Builder | Tách rời việc xây dựng một đối tượng phức tạp khỏi biểu diễn của nó sao cho cùng một tiến trình xây dựng có thể tạo được các biểu diễn khác nhau. |
Factory Method | Định nghĩa interface để sinh ra đối tượng nhưng để cho lớp con quyết định lớp nào được dùng để sinh ra đối tượng |
Prototype | Qui định loại của các đối tượng cần tạo bằng cách dùng một đối tượng mẫu, tạo mới nhờ vào sao chép đối tượng mẫu này. |
Singleton | Đảm bảo 1 class chỉ có 1 instance và cung cấp 1 điểm truy xuất toàn cục đến nó. Thiên hạ đồn rằng đây là 1 anti-pattern, mình tạm thời để đây và không nói gì |
Structural Patterns
Những pattern thuộc nhóm này liên quan đến việc thiết lập và định nghĩa quan hệ giữa các đối tượng. Bao gồm:
Tên | Mục đích |
---|---|
Adapter | chuyển giao diện của một class thành giao diện phù hợp yêu cầu |
Bridge | Tách rời ngữ nghĩa của một vấn đề khỏi việc cài đặt |
Composite | Tổ chức các đối tượng theo cấu trúc phân cấp dạng cây, các đối tượng trong cấu trúc được thao tác theo một cách thuần nhất như nhau. |
Decorator | Gán thêm trách nhiệm cho đối tượng vào lúc chạy (thêm chức năng cho class). |
Facade | Cung cấp một interface cấp cao, dễ dùng cho một tập hợp các interface của hệ thống con (subsystem) |
Flyweight | chia sẻ trạng thái chung nhằm thao tác hiệu quả tài nguyên và bộ nhớ |
Proxy | Cung cấp đối tượng đại diện cho một đối tượng khác để hỗ trợ hoặc kiểm soát quá trình truy xuất đến đối tượng đó |
Behavioral Patterns
Nhóm này liên quan đến việc thực hiện các hành vi của đối tượng. Bao gồm:
Tên | Mục đích |
---|---|
Chain of Responsibility | cho phép truyền request thông qua một chuỗi đối tượng nhận request |
Command | mỗi request hoặc command được đóng gói và gửi đi như một đối tượng |
Interpreter | Hỗ trợ việc định nghĩa biểu diễn văn phạm và bộ thông dịch cho một ngôn ngữ |
Iterator | Truy xuất các phần tử của đối tượng dạng tập hợp tuần tự (list, array, …) |
Mediator | Định nghĩa một đối tượng để điều hướng việc giao tiếp giữa một số đối tượng với nhau. |
Memento | chỉnh sửa và phục hồi trạng thái bên trong của đối tượng mà vẫn không vi phạm việc đóng gói dữ liệu |
Observer | Định nghĩa sự phụ thuộc một-nhiều giữa các đối tượng sao cho khi một đối tượng thay đổi trạng thái thì tất cả các đối tượng phụ thuộc nó cũng thay đổi theo. |
State | Cho phép một đối tượng thay đổi hành vi khi trạng thái bên trong của nó thay đổi |
Strategy | đóng gọi các thuật toán bằng các lớp, mỗi thuật toán có thể thay đổi độc lập đối với chương trình sử dụng thuật toán. Cung cấp một họ giải thuật cho phép client chọn lựa linh động một giải thuật cụ thể khi sử dụng. |
Template Method | Định nghĩa phần khung của một thuật toán, tức là một thuật toán tổng quát gọi đến một số phương thức chưa được cài đặt trong lớp cơ sở; việc cài đặt các phương thức được ủy nhiệm cho các lớp kế thừa. |
Visitor | Cho phép định nghĩa thêm phép toán mới tác động lên các phần tử của một cấu trúc đối tượng mà không cần thay đổi các lớp định nghĩa cấu trúc đó. |
Làm thế nào để lựa chọn design pattern
Với hơn 20 design pattern, vậy làm cách nào để ta tìm được 1 cái mà giải quyết được vấn đề mà mình đang mắc phải, đặt trong trường hợp chúng ta còn khá xa lạ với design pattern. Keke, Gang of Four có gợi ý lại một số cách tiếp cận để tìm ra design pattern phù hợp cho vấn đề:
- Tìm hiểu cách design pattern giải quyết vấn đề
- Tìm hiểu tương quan giữa các pattern với nhau
- Hiểu mục đích của pattern
- Kiểm tra lý do phải thiết kế lại
- Ngược lại với cách tiếp cận trên, thay vì tìm hiểu lý do phải thiết kế lại, thử nghĩ xem bạn muốn thay đổi gì để không phải thiết kế lại
Tóm tắt
Tháng này hơi lười, tạm thời dừng lại ở việc giới thiệu về design pattern. Các phần sau trong series này, mình sẽ tìm hiểu và phân tích kỹ từng pattern và ứng dụng của nó trong một số framework hiện tại.
Tham khảo:
(1) Design Patterns: Elements of Reusable Object-Oriented Software (2) Beginning SOLID Principles and Design Patterns for ASP.NET Developers