1. Trang chủ
  2. » Công Nghệ Thông Tin

tài liệu design patterns

51 621 2

Đ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

Thông tin cơ bản

Định dạng
Số trang 51
Dung lượng 453,78 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

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 đề.

Trang 1

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

Trang 2

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

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ế

Trang 3

đượ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

Trang 4

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)

Trang 5

4.1 Signleton Pattern

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

Trang 6

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()

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

Trang 7

(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:

● Ở 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 đó

(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

Trang 8

- 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

Trang 9

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 Prototype Concrete

public class ConcretePrototype : Prototype<ConcretePrototype>

Trang 10

///<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 Clientpublic 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();

}}

Trang 11

được tạo Nói chung, "factory method" thường được áp dụng cho những phương thức mà nhiệm vụ chính của nó là tạo ra đối tượng.

Mẫu thiết kế Factory sẽ định nghĩa một giao diện (interface) cho việc tạo một đối tượng, nhưng để các lớp con quyết định lớp nào sẽ được tạo "Factory method" giao việc khởi tạo một đối tượng cụ thể cho lớp con."

Khuôn mẫu này phù hợp cho việc tạo các ứng dụng lớn có logic quan hệ phức tạp và cần maintain thường xuyên! Hay các ứng dụng áp dụng cơ chế plugin, hay trong bộ phát triển (toolkit) hoặc framework, ở đó, đoạn mã của framework cần thiết phải tạo một đối tượng là những lớp con của ứng dụng sử dụng framework đó

IProduct và cài đặt các interface

nơi quyết định sẽ gọi xử lý được cài đặt từ ProductA hay ProductB (phụ thuộc High level dùng nó yêu cầu)

tùy vào “hoàn cảnh” khi run-time mà nó sẽ yêu cầu xử lý từ ProductA hay ProductB (Thông qua Creator)

Trang 12

c. Ví dụ

class FactoryPattern{

// Factory Method Pattern interface IProduct

{ string ShipFrom();

} class ProductA : IProduct {

public String ShipFrom() {

return " from South Africa"; }

} class ProductB : IProduct {

public String ShipFrom() {

return "from Spain"; }

} class DefaultProduct : IProduct {

public String ShipFrom() {

return "not available"; }

}

Trang 13

class Creator {

public IProduct FactoryMethod(int month) {

if (month >= 4 && month <= 11) return new ProductA();

Creator c = new Creator();

4.4 Builder Pattern

Builder là mẫu thiết kế hướng đối tượng được tạo ra để chia một công việc khởi tạo phức tạp của một đối tượng ra riêng rẽ từ đó có thể tiến hành khởi tạo đối tượng ở các hoàn cảnh khác nhau

Trang 14

Với những class có chứa nhiều thuộc tính, và việc khởi tạo nên đối tượng phức tạp

có thể dùng mẫu này để dễ quản lý! giảm thiểu số lượng code cần thiết chỉ để đảm nhận một công việc!

- Tình huống áp dụng

o Có cấu trúc bên trong phức tạp (đặc biệt là một biến là một tập các đối tượng liên quan với nhau)

o Có các thuộc tính phụ thuộc vào các thuộc tính khác

o Sử dụng các đối tượng khác trong hệ thống mà có thể khó khởi tạo hoặc khởi tạo phức tạp

tượng Product

Trang 15

● Director: Thực hiện khởi tạo nên các thành phần theo yêu cầu từ Client, xem các dẫn xuất

từ IBuilder như là tham số đầu vào

// Builder uses a complex series of steps

public void Construct(IBuilder builder)

Trang 16

private Product _product = new Product();

public void BuildPartA()

Trang 18

{

// Create director and builders

Director director = new Director();

IBuilder b1 = new ConcreteBuilder1();

IBuilder b2 = new ConcreteBuilder2();

// Construct two products

kế thừa từ một lớp cha thuần ảo gọi là “lớp sản xuất ảo”

b Cấu trúc

Trang 19

Trong đó:

AbstractFactory: định nghĩa một giao tiếp cho thao tác khởi tạo các "sản phẩm"

ảo (AbstractProduct)

ConcreteFactory: thực thi giao tiếp AbstractFactory để tạo ra đối tượng cụ thể

AbstractProduct: định nghĩa một lớp ảo cho một loại đối tương "sản phẩm"

Product: kế thừa từ từ lớp "sản phẩm" ảo AbstractProduct, các lớp Product định

nghĩa từ đối tượng cụ thể

Client: sử dụng các lớp AbstractFactory và AbstractProduct trong hệ thống

Trang 20

// Create and run Africa animal world

ContinentFactory africa = new AfricaFactory(); AnimalWorld world = new AnimalWorld(africa); world.RunFoodChain();

// Create and run America animal world

ContinentFactory america = new AmericaFactory(); world = new AnimalWorld(america);

public abstract Herbivore CreateHerbivore();

public abstract Carnivore CreateCarnivore();

}

///<summary>

/// The 'ConcreteFactory1' class

Trang 22

abstract class Herbivore

Trang 23

/// The 'ProductA2' class

private Herbivore _herbivore;

private Carnivore _carnivore;

Trang 24

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 tham số tới hàm khởi tạo của decorator, decorator sẽ thực thi các chức năng mới Giao diện của đối tượng gốc cần được duy trì qua decorator

Đây là mẫu phù hợp cho các trường hợp nâng cấp, mở rộng ứng dụng Hay được thiết kế trong các hệ thống lớn có các class có vai trò với nhiều đối tượng và với mỗi đối tượng thì có một số xử lý thêm thắt vào Lấy ví dụ như class Window, trong class

hỗ trợ việc vẽ 1 cử sổ với hàm Draw(), nhưng đến lúc nào đó chúng ta cần 1 class vừa cho phép vẽ 1 cử sổ đồng thời trên cửa sổ có thêm thanh cuộn dọc

(ScrollingWindow)!!! Lúc này không nên thêm việc vẽ thêm thanh cuộn dọc vào class

Window, bới vì có thể ảnh hưởng tới các class khác đang sử dụng class Window cũ (ảnh hưởng tới logic của các thành phần đã có sẵn), hoặc dư thừa xử lý không cần thiết Nếu sau này lại muốn thêm thanh cuộn ngang cho cử sổ!???

Cách tốt nhất trong trường hợp này, là tạo 1 class khác với việc bổ sung thêm tính năng vẽ thanh cuộn vào cửa sổ, và khi đó coi đối tượng Window như là đầu vào, khi

đó cử sổ sẽ được trang trí thêm cho phù hợp với yêu cầu!

Trang 25

○ IComponent: Là interface chứa giao diện chung

thêm so với nhu cầu của Client

nó sẽ thêm một số xử lý mới nhằm làm thỏa mãn Client

Xây dựng lớp vẽ ra đối tượng Actor Sau đó sử dụng mẫu Decorator tạo lớp vẽ ra đối tượng Actor có tag mô tả dưới chân Actor

interface Ishape

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

TỪ KHÓA LIÊN QUAN

w