Dạng thức thiết kế

Trong kỹ nghệ phần mềm, một **dạng thức thiết kế** là một giải trình lập lại được cho một dạng vấn đề thường xảy ra trong ngành thiết kế phần mềm. Một dạng thức thiết kế không phải là một thiết kế hoàn tất có thể được chuyển dạng trực tiếp thành mã; nó thực ra là một sự mô tả hay một tiêu bản nhằm chỉ ra cách giải quyết vấn đề mà có thể sử dụng được trong nhiều tình huống khác nhau. Các dạng thức thiết kế hướng đối tượng thường chỉ ra các quan hệ và các mối tương tác giữa các lớp, mà không cần đặc tả rõ các lớp ứng dụng cuối cùng hay các đối tượng có tham gia. Các thuật toán thì không được xem là các dạng thức thiết kế, vì chúng giải quyết các vấn đề tính toán hơn là vấn đề thiết kế.

## Lịch sử
Các dạng thức nguyên thủy như là một nguyên lý thiết kế từ ý kiến của Christopher Alexander. Trong năm 1987, Kent Beck và Ward Cunningham đã bắt đầu thử nghiệm với các ý tưởng về việc ứng dụng các dạng thức vào lập trình và trình bày các kết quả của họ tại hội nghị OOPSLA năm đó. Trong những năm kế tiếp Beck, Cunningham và nhiều người khác đã kế tục công việc này.

Các dạng thức thiết kế trở nên phổ biến trong khoa học máy tính sau khi cuốn *[[Design Patterns|Design Patterns: Elements of Reusable Object-Oriented Software]]* được phát hành trong năm 1944 (Gamma et al). Cùng năm này, hội nghị Pattern Languages of Programs (tên này có nghĩa là "Các Ngôn ngữ Dạng thức của các Chương trình") đã được tổ chức. Năm sau đó, Portland Pattern Repository (tức là "Trung tâm Dữ liệu Dạng thức Portland") đã được hình thành nhằm hồ sơ hóa các dạng thức thiết kế. Nội hàm của thuật ngữ vẫn còn là một việc bàn cãi cho đến thập niên sau đó.

## Ứng dụng
*Dạng thức thiết kế có thể đẩy nhanh quá trình phát triển bằng cách cung ứng các kiểm nghiệm và các mẫu hình phát triển đã được chứng minh. Thiết kế phần mềm có tính hiệu quả đòi hỏi cứu xét tới các vấn đề mà nó không thể thấy trước cho đến giai đoạn lắp đặt sau này. Việc tái dụng các dạng thức thiết kế sẽ giúp tránh khỏi các vấn đề tiềm tàng mà chúng có thể gây ra các khó khăn chính và giúp nâng cao khả năng hiểu được cho người viết mã và cho họ các kiến trúc đi cùng với các dạng thức.
*Thông thường, người ta chỉ hiểu làm thế nào để áp dụng các kĩ thuật thiết kế phần mềm một cách tường minh cho các vấn đề cụ thể. Các kĩ thuật này thì khó để áp dụng lên các vấn đề có điện rộng hơn. Các dạng thức thiết kế cung cấp các lời giải tổng quát, được hồ sơ hóa trong một định dạng mà chúng không đòi hỏi phải dính chặt với các vấn đề riêng biệt.
*Các dạng thức thiết kế được hợp thành từ nhiều đề mục. Đặc biệt thú vị là các đề mục Cấu trúc, các Thành phần và Hợp tác. Các mục này mô tả một "mô típ thiết kế": một vi kiến trúc (*micro architechture*) nguyên mẫu mà các nhà phát triển chép lại và đáp ứng cho các thiết kế riêng của họ để giải quyết vấn đề hiện tại mà đã được mô tả bởi dạng thức thiết kế đó. (Một vi kiến trúc là một bộ các chương trình cấu thành, nghĩa là các lớp, các phương pháp,..., và các quan hệ giữa các cấu thành này). Những người phát triển dùng dạng thức thiết kế này bằng cách dẫn nhập vào các thiết kế của họ cái vi kiến trúc nguyên mẫu này; nghĩa là các vi kiến trúc đó, trong các thiết kế sẽ có cấu trúc và tổ chức tương tự như mô típ thiết kế đã chọn.
* Thêm vào đó, các dạng thức cho phép các nhà phát triển để liên lạc sử dụng các tên nổi tiếng, đã được hiểu tường tận về các tương tác phần mềm. Các dạng thức thiết kế thông dụng có thể dược nâng cao qua thời gian, tạo thêm các thiết kế mạnh hơn là các thiết kế đặc ứng (*ad-hoc*).

## Phân lớp
Các dạng thức thiết kế có thể được phân lớp dựa trên nhiều tiêu chỉ, điểm chung nhất của chúng là vấn đề cơ sở bên trong mà chúng giải quyết. Theo tiêu chỉ này, các dạng thức thiết kế có thể được phân thành nhiều lớp, một số trong các lớp đó là:
* Các Dạng thức nền tảng (*fundamental pattern*)
* Các Dạng thức kiến tạo (*creational pattern*)
* Các Dạng thức cấu trúc (*structural pattern*)
* Các Dạng thức ứng xử (*behavioral pattern*)
* Các Dạng thức đồng tranh (*concurrency pattern*)
* Các Dạng thức kiến trúc (*architectural pattern*)

## Hồ sơ
Hồ sơ cho một dạng thức thiết kế nên chứa đủ thông tin về vấn đề mà dạng thức đó muốn giải quyết, ngữ cảnh mà nó được sử dụng và lời giải đề nghị. Mặc dù vậy, các tác giả sử dụng cách trình bày riêng của họ để viết các dạng thức thiết kế, và các trình bày này thường rập theo những bộ phận trọng yếu. Các tác giả thường bao gồm thêm vào đó các đề mục để cung cấp thêm thông tin, và sắp xếp các bộ phận trọng yếu này vào trong các tiêu chỉ khác nhau, có thể là với các tên khác nhau.

Một định dạng chung được sử dụng bởi "Gang of Four". Nó bao gồm các tiêu chỉ sau:
***Tên dạng thức và Phân lớp** Mỗi dạng thức nên có một tên đặc trung và phân biệt để giúp xác định và tham chiếu. Thêm vào đó, dạng thức này nên được phân lớp dựa trên một sự chia như là mô tả trong phần trước. Cách phân lớp này giúp ích trong việc nhận ra và sử dụng dạng thức.
***Chủ ý**: Tiêu chỉ này nên mô tả mục tiêu của dạng thức và lý do để sử dụng nó. Nó rập theo phần vấn đề của dạng thức.
***Cũng được biết tới như là**: Một dạng thức có thể có nhiều tên. Các tên này nên được mô tả trong tiêu chí này.
***Vận hành**: Tiêu chỉ này cung cấp một tình huống xảy ra của vấn dề và ngữ cảnh trong đó dạng thức này có thể được áp dụng. Bằng cách liên hệ giữa vấn đề với ngữ cảnh, tiêu chỉ này chỉ ra khi nào dùng dạng thức.
***Khả năng ứng dụng**: Phần này bao gồm các tình huống trong đó dạng thức này có thể hữu dụng. Nó biểu thị phần ngữ cảnh của dạng thức.
***Cấu trúc**: Một biểu đồ của dạng thức. Các Sơ đồ lớp và các sơ đồ tương tác có thể được dùng cho mục đích này.
***Các Thành phần**: Một danh mục các lớp và đối tượng được sử dụng trong dạng thức này và vai trò của chúng trong thiết kế.
***Hợp tác**: Mô tả làm thế nào các lớp và đối tượng được sử dụng trong dạng thức tương tác với nhau.
***Các hệ quả**: Phần này mô tả các kết quả, các hiệu ứng phụ, và các sự lược mất do việc sử dụng dạng thức.
***Lắp đặt**: Tiêu chỉ này mô tả sự lắp đặt của dạng thức và biểu thị phần giải đáp của dạng thức. Nó cung cấp các kĩ thuật được sử dụng trong việc lắp đặt dạng thức này và cho các cách thức để thiết lập.
***Mã thí dụ**: Một minh họa làm thế nào dạng thức có thể được dùng trong một ngôn ngữ lập trình.
***Sử dụng đã biết**: Phần này bao gồm các thí dụ về các cách sử dụng trong thực tế của dạng thức này.
***Các dạng thức liên hệ**: Là phần bao gồm các dạng thức khác có vài sự liên hệ tới dạng thức này, và do đó chúng có thể được sử dụng cùng với dạng thúc này hay là được sử dụng thay vì dạng thức này. Nó cũng bao gồm các tương phản của dạng thức này với các dạng thức tương tự.

## Phê bình
Nguyên lý của các dạng thức thiết kế đã bị phê bình bởi một số lãnh vực của khoa học máy tính.

### Nhắm tới sai vấn đề
Điều cần thiết cho các dạng thức kết quả từ việc sử dụng các ngôn ngữ máy tính hay các kĩ thuật thiếu khả năng trườu tượng. Bằng ý tưởng "nhân tử hóa", một nguyên lý không nên được sao chép, mà tốt hơn nên là tham chiếu. Nhưng nếu vật nào đó được tham chiếu thay vì sao chép thì sẽ không có "dạng thức" để đánh nhãn và phân loại. (Paul Graham viết trong bản luận văn *Revenge of the Nerds* (tức là "sự trả thù của những kẻ kỹ tài"):

This practice is not only common, but institutionalized. For example, in the OO world you hear a good deal about "patterns". I wonder if these patterns are not sometimes evidence of case (c), the human compiler, at work. When I see patterns in my programs, I consider it a sign of trouble. The shape of a program should reflect only the problem it needs to solve. Any other regularity in the code is a sign, to me at least, that I'm using abstractions that aren't powerful enough— often that I'm generating by hand the expansions of some macro that I need to write.
 
:*dịch: Thực nghiệm này không những được thông dụng mà còn được khoa học hoá. Chẳng hạn, trong thế giới OO bạn nghe một ý tưởng về các "dạng thức". Tôi tán thán nếu các dạng thức này đôi khi không phải là bằng chứng của trường hợp (c), trình dịch bằng người, trong công việc. Khi tôi thấy các dạng thức trong các chương trình của mình tôi xem đó là dấu hiệu của sự cố. Hình dáng của mt chương trình chỉ nên phản ảnh vấn đề nó cần giải quyết. Mọi sự chính quy trong mã là dấu hiệu, mà ít nhất đối với tôi, là tôi đang sử dụng những sự trừu tượng mà chúng thường không đủ mạnh đến nỗi tôi đang tạo ra bằng tay các sự mở rộng của các [[macro]] mà tôi cần phải viết.*

Peter Norvig cho một bàn cãi tương tự cho rằng 16 trong 23 dạng thức trong cuốn *Design Patterns* ("Các Dạng thức Thiết kế") (mà chủ yếu tập trung trong C++) là đơn giản và loại bỏ được (qua việc hỗ trợ ngôn ngữ trực tiếp) trong Lisp hay trong Dylan.

Các bàn cãi xa hơn được tìm thấy trong bài Portland Pattern Repository.

### Thiếu các nền tảng chuẩn
Sự nghiên cứu về các dạng thức thiết kế đã trởo nên quá "đặc ứng" (*ad hoc*), và một số người cho rằng nguyên lý này cần được chuẩn hóa nhiều hơn. Tại OOPSLA 1999, Gang of Four với sự cồng tác đã đồng thanh chống lại màn xử án, trong đó, họ là những người trách nhiệm chính với các tội phạm chống lại khoa học máy tính. Họ đã bị kết án bởi 2/3 của bồi thẩm đoàn. Một số người cảm thấy rằng sự ảnh hưởng từ lý thuyết tương đối có thể giúp họ tốt hơn là xác định, nghiên cứu, hay chuẩn hoá các dạng thức.

### Dẫn tới các lời giải không hiệu quả
Ý tưởng của một dạng thức thiết kế là một nỗ lực để chuẩn hóa cái mà đã được chấp nhận là các thực nghiệm tốt nhất. Trong nguyên tắc, điều này có thể dường như có ích, nhưng trong thực tế, nó thường dẫn tới kết quả trong sự trùng lặp mã một cách không cần thiết. Hầu như luôn luôn là có một lời giải hiệu quả để sử dụng cho sự thiết lập có tính nhân tố tốt đẹp hơn là một dạng thức thiết kế "chỉ vừa đủ tốt".

### Nguyên lý cũ và hiển nhiên
Từ khi bắt đầu, các nguyên lý khoa học máy tính đã được đặt tên (như là truy ngược, *backtrackting*, hay là cây AVL) và được hồ sơ hoá. Các dạng thức như là được giới thiệu trong cuốn *Design Patterns* được liên hệ đến các hướng dẫn và các nguyên lý liên hệ http://www.lukew.com/ff/entry.asp?348. Trong ngành thiết kế cũng đã có các ngành dùng cho tái dụng các cấu trúc thiết kế (http://rd13doc.cern.ch/Notes/004/Note004-7.html ).

## Ghi chú

## Tham khảo

*
*
*
*
*
*
*
*
*
* Fowler, Martin. Patterns  [software patterns] Software, IEEE, Volume: 20, Issue: 2, March-April 2003. Pages: 56 &ndash; 57.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*

## Liên kết ngoài

*The PatternShare community  - a community site for sharing patterns.
*Directory of websites that provide pattern catalogs  at hillside.net.
*Ward Cunningham's ''Portland Pattern Repository''.
*