12/08/2018, 15:33

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 patternbehavioral 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

0