tài liệu design patterns

51 620 2
tài liệu design patterns

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

Design Pattern (mẫu thiết kế) là vấn đề tất cả những ai thiết kế phần mềm đều phải nắm vững. Tài liệu này mô tả những mẫu thiết kế phổ biến bao gồm cả mã nguồn minh họa cho các mẫu nhằm mục đích hỗ trợ những người mới bắt đầu nghiên cứu về mẫu thiết kế dễ hiểu vấn đề.

Mục lục I. Giới thiệu 1. Tổng quan về tình hình nghiên cứu thuộc lĩnh vực của đề tài Mẫu thiết kế đã được nghiên cứu từ những năm 1990, nó trở được phổ biến trong khoa học máy tính kể từ khi cuốn sách “Design Patterns: Elements of Reusable Object-Oriented Software” của nhóm bốn tác giả Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides ra đời. Trong cuốn sách này các tác giả đã đưa ra 23 mẫu thiết kế trong thiết kế phần mềm. Ngày nay bên cạnh các mẫu này thì đã có thêm một số mẫu thiết kế mới. Việc nắm vững và vận dụng những mẫu thiết kế để có được phần mềm có chất lượng tốt là một vấn đề không hề đơn giản với một kỹ sư phần mềm. 2. Mục tiêu nghiên cứu của đề tài Nghiên cứu một số mẫu thiết kế thông dụng trong thiết kế phần mềm. Xây dựng thành một tài liệu tham khảo về mẫu thiết kế cho sinh viên chuyên ngành phần mềm khoa công nghệ Thông, trường Đại học Xây dựng. 3. Nội dung nghiên cứu o Nghiên cứu lịch sử phát triển, vài trò của mẫu thiết kế trong thiết kế phần mềm o Phân loại mẫu thiết kế 1 o Nghiên cứu một số mẫu thiết kế phổ biến: FACTORY PATTERN, ABSTRACT FACTORY PATTERN, SINGLETON PATTERN, PROXY PATTERN, ADAPTER PATTERN, WRAPPER PATTERN 4. Phương pháp nghiên cứu Đề tài sử dụng phương pháp tiếp cận tài liệu tham khảo, nghiên cứu mô hình hóa bằng UML của các mẫu thiết kế, cài đặt các mẫu bằng ngôn ngữ lập trình C# để minh họa một cách trực quan nhất các mẫu thiết kế. II. Nội dung nghiên cứu 1. Mẫu thiết kế là gì? Trong phát triển phần mềm hiện đại, kiến trúc tổng thể của dự án đóng một vai trò quan trọng, đặc biệt với bộ khung (framework) và mẫu thiết kế. Mẫu thiết kế mô tả một giải pháp chung đối với một vấn đề nào đó trong thiết kế thường được “lặp lại” trong nhiều dự án. Nói một cách khác, một mẫu thiết kế có thể được xem như một “khuôn mẫu” có sẵn áp dụng được cho nhiều tình huống khác nhau để giải quyết một vấn đề cụ thể. Trong bất kỳ hệ thống phần mềm hướng đối tượng nào chúng ta cũng có thể bắt gặp các vấn đề lặp lại. Mẫu thiết kế cũng cung cấp những thuật ngữ và khái niệm chung trong thiết kế. Nói một cách đơn giản, khi đề cập đến một mẫu thiết kế nào đấy, bất kỳ ai biết mẫu thiết kế đến đều có thể nhanh chúng hình dung ra “bức tranh” của giải pháp. Và cuối cùng, nếu áp dụng mẫu thiết kế hiệu quả thì việc bảo trì phần mềm cũng được tiến hành thuận lợi hơn, nắm bắt kiến trúc hệ thống nhanh hơn. Mẫu thiết kế hỗ trợ tái sử dụng kiến trúc và mẫu hình thiết kế phần mềm theo quy mô lớn. Cần phân biệt muẫu thiết kế với framework. Framework hỗ trợ tái sử dụng mô hình thiết kế và mã nguồn ở mức chi tiết hơn. Trong khi đó, mẫu thiết kế được vận dụng ở mức tổng quát hơn, giúp các nhà phát triển hình dung và ghi nhận các cấu trúc tĩnh và động cũng như quan hệ tương tác giữa các giải pháp trong quá trình thiết kế ứng dụng đối với một chuyên khu riêng biệt. Mẫu thiết kế đa tương thích, mẫu thiết kế không phụ thuộc vào ngôn ngữ lập trình, công nghệ hoặc các nền tảng lớn như J2EE của Sun hay Microsoft .NET Framework. Tiềm năng ứng dụng của mẫu thiết kế là rất lớn. Các thiết kế dựa trên mẫu thiết kế 2 được sử dụng khá nhiều ở các phần mềm mã nguồn mở, trong nền tảng J2EE hoặc .NET Trong các dạng ứng dụng này, có thể dễ dàng nhận ra một số tên lớp chứa các tiền tố hoặc hậu tố như Factory, Proxy, Adapter Việc nắm vững các mẫu để áp dụng thiết kế kiến trúc phần mềm là rất quan trọng với một kỹ sư công nghệ thông tin. Mục tiêu của đề tài này nhằm nghiên cứu một số mẫu thiết kế thông dụng trong thiết kế hướng đối tượng từ đó xây dựng thành một tài liệu tham khảo cho sinh viên ngành công nghệ phần mềm, Khoa Công nghệ Thông tin, trường Đại học Xây dựng. 2. Lịch sử phát triển Ý tưởng dùng mẫu xuất phát từ ngành kiến trúc, Alexander, Ishikawa, Silverstein, Jacobson, Fiksdahl-King và Angel (1977) lần đầu tiên đưa ra ý tưởng dùng các mẫu chuẩn trong thiết kế xây dựng và truyền thông. Họ đã xác định và lập sưu liệu các mẫu có liên quan để có thể dùng để giải quyết các vấn đề thường xảy ra trong thiết kế các cao ốc. Mỗi mẫu này là một cách thiết kế, chúng đã được phát triển hàng trăm năm như là các giải pháp cho các vấn đề mà người ta làm trong lĩnh vực xây dựng thường gặp. Các giải pháp tốt nhất có được ngày hôm nay là qua một quá trình sàng lọc tự nhiên. Mặc dù nghành công nghệ phần mềm không có lịch sử phát triển lâu dài như nghành kiến trúc, xây dựng nhưng Công nghệ phần mềm là một nghành công nghiệp tiên tiến, tiếp thu tất cả những gì tốt đẹp nhất từ các nghành khác. Mẫu được xem là giải pháp tốt để giải quyết vấn đề xây dựng hệ thống phần mềm. Suốt những năm đầu 1990, mẫu thiết kế được thảo luận ở các hội thảo workshop, sau đó người ta nổ lực để đưa ra danh sách các mẫu và lập sưu liệu về chúng. Những người tham gia bị dồn vào việc cần thiết phải cung cấp một số kiểu cấu trúc ở một mức quan niệm cao hơn đối tượng và lớp để cấu trúc này có thể được dùng để tổ chức các lớp. Đây là kết quả của sự nhận thức đựơc rằng việc dùng các kỹ thuật hướng đối tượng độc lập sẽ không mang lại những cải tiến đáng kể đối với chất lượng cũng như hiệu quả của công việc phát triển phần mềm. Mẫu được xem là cách tổ chức việc phát triển hướn g đối tượng, cách đóng gói các kinh nghiệm của những ngưòi đi trước và rất hiệu quả trong thực hành. Năm 1994 tại hội nghị PloP ( Pattern Languageof Programming Design) đã được tổ chức. Cũng trong năm này quyển sách Design patterns : Elements of Reusable Object Oriented 3 Software (Gamma, Johnson,Helmvà Vhissdes,1995) đã được xuất bản đúng vào thời điểm diễn ra hội nghị OOPSLA’94. Đây là một tài liệu còn phôi thai trong việc làm nỗi bật ảnh hưởng của mẫu đối với việc phát triển phần mềm, sự đóng góp của nó là xây dựng các mẫu thành các danh mục (catalogue) với định dạng chuẩn được dùng làm tài liệu cho mỗi mẫu và nổi tiếng với tên Gang of Four (bộ tứ) và các mẫu nó thường được gọi là các mẫu Gang of Four. Còn rất nhiều các cuốn sách khác xuất hiện trong 2 năm sau, và các định dạng chuẩn khác được đưa ra. Năm 2000 Evitts có tổng kết về cách các mẫu xâm nhập vào thế giới phần mềm (sách của ông lúc bấy giờ chỉ nói về những mẫu có thể được sử dụng trong UML chứ chưa đưa ra khái niệm những mẫu thiết kế một cách tổng quát). Ông công nhận Kent Beck và Ward Cunningham là những người phát triển những mẫu đầu tiên với SmallTalk trong công việc của họ được báo cáo tại hội nghị OOPSLA’87. Có 5 mẫu mà Kent Beck và Ward Cunningham đã tìm ra trong việc kết hợp các người dùng của một hệ thống mà họ đangthiết kế. Năm mẫu này đều được áp dụng để thiết kế giao diện người dùng trong môi trường Windows. 3. Phân loại mẫu thiết kế Mẫu thiết kế được phân loại ra làm 3 nhóm chính sau đây: • Nhóm cấu thành (Creational Pattern): Gồm Factory, Abstract Factory, Singleton, Prototype, Builder Liên quan đến quá trình khởi tạo đối tượng cụ thể từ một định nghĩa trừu tượng (abstract class, interface). • Nhóm cấu trúc tĩnh (Structural Pattern): Gồm Proxy, Adapter, Wrapper, Bridge, Facade, Flyweight, Visitor Liên quan đến vấn đề làm thế nào để các lớp và đối tượng kết hợp với nhau tạo thành các cấu trúc lớn hơn. • Nhóm tương tác động (Behavioral Pattern): Gồm Observer, State, Command, Iterator Mô tả cách thức để các lớp hoặc đối tượng có thể giao tiếp với nhau. Dưới đây chúng ta sẽ tìm hiểu chi tiết một số pattern tiêu biểu nhất: Factory method, Abstract Factory, Singleton, Proxy, Adapter, Prototype, Builder, Bridge, Observer, Iterator. Chúng ta quy ước với nhau rằng “giao diện lớp” được hiểu như interface hoặc abstract class vì đây đơn thuần là các định nghĩa lớp. 4. Nhóm cấu thành (Creational Patterns) 4 4.1 Signleton Pattern a. Mục đích, ý nghĩa Singleton có lẽ là một trong những mẫu có tính trừu tượng dễ hiểu nhất mà người học về mẫu thiết kế nào cũng biết. Singleton đảm bảo rằng một class có duy nhất một thực thể (instance) hay đối tượng (object) và cung cấp một cách thức truy nhập toàn cục để có thể từ bất kỳ đâu cũng lấy được instance duy nhất đó. Chúng ta cũng gọi thực thể duy nhất đó là thực thể chính (solely) của class đó. Đối với một vài class thì việc chỉ có duy nhất một instance (object) là rất quan trọng. Mặc dù có rất nhiều máy in trong hệ thống nhưng chỉ có một printer spooler. Cũng chỉ có một file system và một windows manager. Cũng như trong thiết kế connection pool thì chỉ có một connection pool quản lý nhiều connection. Làm thế nào để chúng ta đảm bảo một class chỉ có một thể hiện duy nhất và dễ dàng truy nhập được? Một object toàn cục có thể làm cho nó dễ dàng truy nhập được nhưng không ngăn cấm bạn tạo thêm nhiều object khác. Một giải pháp tốt hơn là làm cho class đó tự bản thân nó có thể điều khiển được thực thể chính của nó. Class đó có thể đảm bảo rằng không có thực thể khác được tạo ra (bằng cách chặn đứng các yêu cầu tạo object mới) và cung cấp cách thức để truy nhập được thực thể chính của nó. Đó là mẫu singleton. b. Cấu trúc c. Ví dụ 5 Xây dựng một lớp cho phép tạo ra một đối tượng form duy nhất. public partial class frmSearch : Form { private static frmSearch afrmSearch =null; public static frmSearch Instance() { if (afrmSearch == null) afrmSearch = new frmSearch(); return afrmSearch; } } } 4.2 Prototype Pattern a. Mục đích, ý nghĩa Prototype pattern giúp cho việc khởi tạo object bằng một object nguyên mẫu (prototype), là bản sao của object “mẫu” đó. Ý tưởng của mẫu là chúng ta được cung cấp một object và sẽ dùng chính object này để như là một hình mẫu (template) khi cần tạo lập một đối tượng mới. Việc tạo lập object mới sẽ dựa trên object mẫu mà không sử dụng toán tử new hoặc constructor … được cung cấp bởi ngôn ngữ lập trình. Lý do là chúng ta không biết được thông tin nội tại chi tiết bên trong object và object có thể che dấu và chỉ cung cấp ra bên ngoài một lượng thông tin giới hạn. Do vậy ta không thể dùng toán tử new và sao chép những dữ liệu được object cung cấp 6 (vốn không đầy đủ) cho một object mới. Cách tốt nhất là để cho chính object “mẫu” tự xác định thông tin và dữ liệu sao chép. Bài toán đặt ra: ● Có 1 class A gồm những thuộc tính private và public ● Ở 1 client X nào đó, đã tạo 1 object a (thể hiện của class A) và set các giá trị cho object đó ● Làm thế nào để sao chép 1 object tương tự như object a có đầy đủ thông tin như object a (cả thông tin private và public)? Sở dĩ có bài toán này bởi vì thực tế nhiều khi đang tồn tại 1 object, chúng ta muốn tạo 1 object khác nhưng không thể gán đối tượng theo cách thông thường, vì như thế đối tượng được gán và đối tượng gốc sẽ cùng tham chiếu đến 1 vùng bộ nhớ, khi object gốc hay object copy bị thay đổi sẽ làm thay đổi dữ liệu của object còn lại. Điều này làm ảnh hưởng đến logic của chương trình. Chính vì thế cần thiết phải có 1 cơ chế để sao chép lại những object va object sao chép sẽ tự tạo ra 1 vùng nhớ để lưu trữ dữ liệu. Giải pháp: Ở class A tạo 1 phương thức cho phép sao chép 1 đối tượng với những dữ liệu hiện có của đôi tượng đó! b. Cấu trúc - Prototype: Cung cấp interface để copy chính bản thân nó (phương thức Clone()) 7 - ConcreatePrototype: Implement interface được cung cấp bởi Prototype để copy chính bản thân nó. - Client: Tạo một object mới bằng cách yêu cầu prototype copy chính bản thân nó. Prototype ẩn đi những lớp con rời rạc từ phía client, do vậy làm giảm đi số lớp con mà client cần biết. Hơn thế nữa pattern này làm cho client hoạt động với những lớp con cụ thể mà không phải thay đổi gì. Sau đây là một vài lợi ích khác của prototype pattern: - Thêm và loại bỏ lớp concreate lúc run-time: Prototype hợp nhất quá trình khởi tạo một object mới vào trong hệ thống đơn giản chỉ bằng cách đăng ký một thực thể nguyên mẫu với client. Điều đó linh động hơn một chút so với các mẫu kiến tạo khác bởi vì client có thể cài đặt và loại bỏ các nguyên mẫu tại thời điểm run-time. - Khởi tạo object mới bằng cách thay đổi một vài attribute của object (các object có ít điểm khác biệt nhau): Một hệ thống linh động sẽ để cho chúng ta tự define một hành động nào đó thông qua sự kết hợp với một object (nghĩa là một phương thức của một class) hơn là define một class mới. Client có thể thể hiện một tác động khác bằng cách ủy quyền cho lớp prototype. Đồng thời cách thức khởi tạo này cũng giúp cho chúng ta khai báo một “lớp mới” mà không phải lập trình gì cả. Thực tế thì việc copy một nguyên mẫu giống như việc khởi tạo một object từ một class mới. Prototype pattern giúp giảm số lớp mà hệ thống cần dùng. - Khởi tạo object mới bằng cách thay đổi cấu trúc: Rất nhiều ứng dụng xây dựng hệ thống từ nhiều phần và các phần con. Các phần con lại khởi tạo từ nhiều phần con khác (chia nhỏ bài toán). Prototype pattern cũng hỗ trợ điều này. Nghĩa là các phần đó có thể được khởi tạo từ việc copy một nguyên mẫu từ một “cấu trúc” khác. Miễn là các phần kết hợp đều thể hiện Clone() và được sử dụng với cấu trúc khác nhau làm nguyên mẫu. - Giảm việc phân lớp: Đôi khi hệ thống quá phức tạp vì có quá nhiều class, và cây thừa kế của lớp khởi tạo có quá nhiều lớp song song cùng mức. Prototype pattern rõ ràng làm giảm số lớp và sự phức tạp của cây thừa kế (class hierarchy) Một điểm hạn chế của prototype pattern là đôi khi việc phải implement mỗi phương thức clone() của mỗi lớp con của Prototype sẽ gặp khó khăn. Ví dụ như việc 8 implement clone() sẽ khó khăn khi mà những object nội hàm của chúng không hỗ trợ việc copy hoặc có một reference (không copy được reference). c. Ví dụ #region The Prototype public abstract class Prototype<T> { #region Methods public T Clone() { // create a shallow copy of the object return (T)this.MemberwiseClone(); } #endregion } #endregion #region Prototype Concrete public class ConcretePrototype : Prototype<ConcretePrototype> { private string _strName; /// <summary> /// The name of the prototype /// </summary> public string Name { get { return _strName; } } 9 /// <summary> /// Construct a new ConcretePrototype with the /// given name. /// </summary> /// <param name="name">The given name</param> public ConcretePrototype(string name) { _strName = name; } } #endregion Prototype Concrete #region Client public class Client { protected void Operation() { // Create new object 1, only first object is create ConcretePrototype obj1 = new ConcretePrototype("Hello world!"); // Copy object obj1 to obj2 ConcretePrototype obj2 = (ConcretePrototype)obj1.Clone(); } } #endregion client 4.3 Factory Method Pattern a. Mục đích, ý nghĩa Factory method là một mẫu thiết kế hướng đối tượng, nhằm giải quyết vấn đề tạo một đối tượng mà không cần thiết chỉ ra một cách chính xác lớp nào sẽ được tạo. Factory method giải quyết vấn đề này bằng cách định nghĩa một phương thức cho việc tạo đối tượng, và các lớp con thừa kế có thể override để chỉ rõ đối tượng nào sẽ 10 [...]... AbstractProduct trong hệ thống c Ví dụ using System; using System.Collections.Generic; using System.Linq; using System.Text; 19 namespace AbstractFactoryRealWorld { /// /// Abstract Factory Design Pattern /// class Program { static void Main(string[] args) { // Create and run Africa animal world ContinentFactory africa = new AfricaFactory(); AnimalWorld world = new AnimalWorld(africa);... factory) { _carnivore = factory.CreateCarnivore(); _herbivore = factory.CreateHerbivore(); 23 } public void RunFoodChain() { _carnivore.Eat(_herbivore); } } } 5 Nhóm các mẫu cấu trúc tĩnh (Structural Patterns) a 5.1 Decorator Pattern Mục đích, ý nghĩa Mẫu trang trí làm việc bằng cách đóng gói đối tượng gốc vào trong một đối tượng "trang trí" mới, thường đạt được bằng cách truyền đối tượng gốc như một... đối tượng mà không gây ra xung đột Thực tế có rất nhiều tình huống khiến chúng ta phải nghĩ đến 28 thiết kế này Một synchronization proxy được thiết lập có thể kiểm soát được nhiều yêu cầu cập nhật dữ liệu một cách đồng thời, tại thời điểm bắt đầu cập nhật chỉ có một client với mức ưu tiên cao nhất giành được khoá để đánh dấu rằng các client khác cần phải chờ đến lượt Synchronization proxy hoạt động... đến đối tượng đó • Cả proxy và đối tượng đích đều kế thừa hoặc thực thi chung một lớp giao diện Mã máy dịch cho lớp giao diện thường “nhẹ” hơn các lớp cụ thể và do đó có thể giảm được thời gian tải dữ liệu giữa server và client b Cấu trúc 29 ● ISubject: Là interface cung cấp giao diện chung ● Subject: Là class đích, cung cấp các xử lý mà Client yêu cầu ● Proxy: Là class trung gian, ở đây sẽ đánh giá . void Show() { Console.WriteLine(" Product Parts "); foreach (string part in _parts) { Console.WriteLine(part); } } /// <summary> /// Entry point into console application. . Cũng trong năm này quyển sách Design patterns : Elements of Reusable Object Oriented 3 Software (Gamma, Johnson,Helmvà Vhissdes,1995) đã được xuất bản đúng vào thời điểm diễn ra hội nghị OOPSLA’94 Ông công nhận Kent Beck và Ward Cunningham là những người phát triển những mẫu đầu tiên với SmallTalk trong công việc của họ được báo cáo tại hội nghị OOPSLA’87. Có 5 mẫu mà Kent Beck và Ward

Ngày đăng: 27/10/2014, 14:53

Mục lục

  • 1. Mẫu thiết kế là gì?

  • 2. Lịch sử phát triển

  • 3. Phân loại mẫu thiết kế

  • Tài liệu tham khảo

Tài liệu cùng người dùng

Tài liệu liên quan