Tải bản đầy đủ (.pdf) (113 trang)

Phát triển mẫu thiết kế phần mềm và ứng dụng

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (1.89 MB, 113 trang )






ĐẠI HỌC QUỐC GIA HÀ NỘI
TRƯỜNG ĐẠI HỌC CÔNG NGHỆ









NGHIÊM VĂN TRIỆU




PHÁT TRIỂN MẪU THIẾT KẾ PHẦN MỀM
VÀ ỨNG DỤNG



LUẬN VĂN THẠC SĨ















HÀ NỘI - 2010






ĐẠI HỌC QUỐC GIA HÀ NỘI
TRƯỜNG ĐẠI HỌC CÔNG NGHỆ








NGHIÊM VĂN TRIỆU





PHÁT TRIỂN MẪU THIẾT KẾ PHẦN MỀM
VÀ ỨNG DỤNG




Ngành: Công nghệ thông tin
Chuyên ngành: Công nghệ phần mềm
Mã số: 60 48 10


LUẬN VĂN THẠC SĨ


NGƯỜI HƯỚNG DẪN KHOA HỌC: PGS.TS ĐOÀN VĂN BAN






HÀ NỘI - 2010



MỤC LỤC

MỞ ĐẦU 1

CHƢƠNG 1. TỔNG QUAN VỀ MẪU THIẾT KẾ PHẦN MỀM 2
1.1. Vấn đề trong thiết kế phần mềm hƣớng đối tƣợng 2
1.2. Khái niệm Mẫu thiết kế 2
1.3. Nội dung các mẫu thiết kế GOF [6] 2
1.3.1. Nhóm mẫu tạo lập 2
1.3.2. Nhóm Mẫu cấu trúc 12
1.3.3. Nhóm mẫu hành vi 25
1.4. Tổng kết chƣơng 47
CHƢƠNG 2. CÁC NGUYÊN LÝ THIẾT KẾ MẪU PHẦN MỀM 49
2.1. Các nguyên lý thiết kế hƣớng đối tƣợng [10] 49
2.1.1. Nguyên lý đóng mở 49
2.1.2. Nguyên lý Nghịch đảo phụ thuộc 52
2.1.3. Nguyên lý Thay thế Liskov 54
2.1.4. Nguyên lý Phân tách giao diện 55
2.2. Các nguyên lý xây dựng mẫu thiết kế phần mềm 58
2.2.1. Tình huống phát sinh mẫu thiết kế là từ nguyên lý thiết kế và thực tiễn 58
2.2.2. Mẫu thiết kế là giải pháp cụ thể 58
2.2.3. Mục tiêu thiết kế mẫu là hƣớng tới ngƣời dùng 59
2.2.4. Các thuật ngữ trong mẫu thiết kế điển hình và gợi vấn đề 60
2.2.5. Lựa chọn các tình huống áp dụng điển hình 60
2.3. Tổng kết chƣơng 61
CHƢƠNG 3. PHƢƠNG PHÁP THIẾT KẾ MẪU PHẦN MỀM 62
3.1. Các thành phần cơ bản của mẫu thiết kế 62
3.1.1. Tên khuôn mẫu 62
3.1.2. Vấn đề 62
3.1.3. Giải pháp 62
3.1.4. Hệ quả 63
3.2. Các định dạng mẫu thiết kế 63
3.2.1. Định dạng Alexandrian 63
3.2.2. Định dạng GOF 64

3.2.3. Định dạng Porland 64
3.2.4. Định dạng Coplien 65
3.2.5. Định dạng POSA 65
3.2.6. Định dạng P of EAA 65
3.3. Định dạng GoF của mẫu thiết kế 65
3.4. Việc lựa chọn định dạng mẫu thiết kế 67
3.5. Tổng kết chƣơng 67
CHƢƠNG 4. PHÁT TRIỂN MẪU THIẾT KẾ VÀ ỨNG DỤNG 69
4.1. Các mẫu thiết kế đối tƣợng 69
4.1.1. Mẫu đối tƣợng trống 69
4.1.2. Mẫu đối tƣợng vai trò 74
4.1.3. Mẫu đối tƣợng mở rộng 83
4.1.4. Mẫu đối tƣợng kiểu 90
4.2. Mẫu thiết kế Ajax 96
4.2.1. Tổng quan về Ajax 96



4.2.2. AJAX là gì 97
4.2.3. AJAX hoạt động nhƣ thế nào 97
4.2.4. Các ứng dụng AJAX phổ biến 99
4.2.5. Tổng quan về mẫu thiết kế Ajax 99
4.3. Ứng dụng mẫu thiết kế trong thiết kế khung cho tầng truy cập dữ liệu 101
4.3.1. Đặt vấn đề 101
4.3.2. Mô hình 3 tầng 101
4.3.3. Cài đặt mô hình khung cho tầng truy cập dữ liệu 102
4.4. Tổng kết chƣơng 106
KẾT LUẬN 107
TÀI LIỆU THAM KHẢO 108






DANH MỤC HÌNH VẼ

Hình 1.1. Sơ đồ lớp mẫu Abstract Factory 3
Hình 1.2. Sơ đồ lớp mẫu Abstract Factory 4
Hình 1.3. Sơ đồ lớp mẫu Builder 7
Hình 1.4. Sơ đồ lớp mẫu Factory Method 9
Hình 1.5. Sơ đồ lớp mẫu Prototype 10
Hình 1.6. Sơ đồ lớp mẫu Singleton 12
Hình 1.7. Sơ đồ lớp mẫu Adapter 13
Hình 1.8. Sơ đồ lớp mẫu Bridge 14
Hình 1.9. Sơ đồ lớp minh họa 16
Hình 1.10. Sơ đồ phân cấp 16
Hình 1.11. Sơ đồ lớp mẫu Composite 17
Hình 1.12. Sơ đồ lớp mẫu Decorator 19
Hình 1.12. Sơ đồ minh họa 20
Hình 1.13. Sơ đồ lớp mẫu Facade 20
Hình 1.14. Sơ đồ lớp mẫu Flyweight 22
Hình 1.15. Sơ đồ lớp mẫu Proxy 24
Hình 1.16. Sơ đồ tƣơng tác 26
Hình 1.17. Biểu đồ cộng tác 26
Hình 1.18. Mô hình lớp 27
Hình 1.19. Sơ đồ lớp mẫu Chain of Responsibility 27
Hình 1.20. Mô hình tƣơng tác 29
Hình 1.21. Sơ đồ lớp mẫu Command 29
Hình 1.22. Mô hình cấu trúc 31
Hình 1.22. Mô hình cây phân cấp 32

Hình 1.23. Sơ đồ lớp mẫu Interperter 33
Hình 1.24. Mô hình tƣơng tác 35
Hình 1.25. Sơ đồ lớp mẫu Iterator 35
Hình 1.26. Hộp thoại biểu diễn các widget 37
Hình 1.27. Biều đồ đối tƣợng 38
Hình 1.28. Biều đồ diễn tiến 38
Hình 1.29. Biều đồ lớp 39
Hình 1.30. Sơ đồ lớp mẫu Mediator 39
Hình 1.31. Sơ đồ lớp mẫu Memento 41
Hình 1.32. Sơ đồ lớp mẫu Observer 42
Hình 1.33. Sơ đồ lớp mẫu State 43
Hình 1.34. Sơ đồ lớp mẫu Strategy 44
Hình 1.35. Sơ đồ lớp mẫu Template Method 45
Hình 1.36. Sơ đồ lớp mẫu Visitor 46
Hình 2.1. Mô hình thừa kế lớp 56
Hình 2.2. Mô hình thừa kế lớp cải tiến 57
Hình 4.1. Sơ đồ lớp mẫu Null Object 70
Hình 4.2. Sơ đồ lớp nghiệp vụ ngân hàng 75
Hình 4.3. Sơ đồ phân lớp 76
Hình 4.4. Sơ đồ lớp mẫu Role Object 77
Hình 4.5. Sơ đồ lớp mẫu Role Object đệ quy 81




Hình 4.6. Sơ đồ tƣơng tác giữa các vai trò và lõi 81
Hình 4.7. Sơ đồ lớp minh họa 85
Hình 4.8. Sơ đồ lớp mẫu Extension Object 86
Hình 4.9. Sơ đồ lớp mẫu Extension Object rút gọn 88
Hình 4.10. Sơ đồ lớp Movie, Videotape 91

Hình 4.11. Sơ đồ lớp, đối tƣợng 91
Hình 4.12. Sơ đồ lớp mẫu Type Object 92
Hình 4.13. Sơ đồ lớp, đối tƣợng mẫu Type Object 93
Hình 4.14. Ứng dụng web truyền thống (trái) và ứng dụng AJAX 98
Hình 4.15. Tƣơng tác đồng bộ trong ứng dụng web truyền thống (trên) và dị bộ trong
ứng dụng AJAX. 98
Hình 4.16. Nhóm các mẫu AJAX. 100
Hình 4.17. Mô hình ứng dụng 3-tầng 101
Hình 4.18. Biểu đồ lớp của tầng truy cập dữ liệu 103




HỆ THỐNG CÁC TỪ VIẾT TẮT

Kí hiệu viết tắt
Tên tiếng Anh
Ý nghĩa
GoF
Gang of Four

OMT
Object Modeling Technique
Kỹ thuật mô hình hóa đối tƣợng
AJAX
Asynchronous JavaScript
and XML
JavaScript và XML không đồng
bộ
UI

User Interface
Giao diện ngƣời dùng
PL
Presentation Layer
Tầng trình diễn
BL
Business Layer
Tầng nghiệp vụ
DL
Data Layer
Tầng dữ liệu


1


MỞ ĐẦU
Một trong những tiêu chuẩn quan trọng để đánh giá chất lƣợng phần mềm là khả
năng tái sử dụng. Thực tế cho thấy mỗi dự án phần mềm là một thực thể phức tạp và
duy nhất. Nhƣng giữa các thực thể đó ta vẫn tìm thấy sự lặp lại ở một hoặc nhiều điểm.
Qua quá trình nghiên cứu, hƣớng giải quyết cho các vấn đề mang tính chất lặp đi lặp
lại khi phát triển các hệ thống phần mềm đã đƣợc các chuyên gia đúc kết và nâng lên
mức tổng quát. Từ đó hình thành khái niệm mẫu thiết kế.
Năm 1995, Erich Gamma và các cộng sự của ông đã công bố cuốn sách
“Elements of reusable Object Oriented Software” và đã đánh dấu sự ra đời của thiết
kế mẫu. Đây là bƣớc tiến vô cùng quan trọng đối với việc thiết kế phần mềm hƣớng
đối tƣợng.
Hiện nay, nhiều hệ thống phần mềm đƣợc thiết kế theo cách tiếp cận hƣớng đối
tƣợng và áp dụng mô hình mẫu thiết kế (Design Pattern). Mẫu thiết kế giúp ta giải
quyết bài toán nhanh gọn, có khả năng tái sử dụng mà không cần phải thiết kế lại. Mẫu

thiết kế dựa trên nguyên lý thiết kế hƣớng đối tƣợng và nó đƣợc xem nhƣ là công cụ
để phát hiện và mô tả bài toán ở mức trừu tƣợng cao mà vẫn bao hàm đầy đủ ngữ
nghĩa của bài toán ứng dụng.
Erich Gamma và các cộng sự đã đƣa ra 23 mẫu thiết kế nổi tiếng (các mẫu GOF
– Gang of Four). Các mẫu thiết kế đó đã đƣợc áp dụng rất thành công trong thiết kế
các phần mềm hƣớng đối tƣợng. Tuy nhiên với sự phát triển nhanh chóng của công
nghiệp phần mềm và phƣơng pháp thiết kế hƣớng đối tƣợng, đã nảy sinh rất nhiều tình
huống đòi hỏi và phát sinh những mẫu thiết kế mới cho phù hợp. Cho đến nay đã có
rất nhiều các mẫu thiết kế đã đƣợc đƣa ra dựa trên việc cải biến các mẫu trên cũng nhƣ
các mẫu thiết kế mới. Do đó cần thiết có những nghiên cứu phƣơng pháp luận về mẫu
thiết kế. Đồng thời trên cơ sở đó đƣa ra các phƣơng pháp để xây dựng lên các mẫu
thiết kế trong những tình huống phát sinh. Vì vậy tôi đã lựa chọn đề tài “Phát triển
mẫu thiết kế phần mềm và ứng dụng” để tìm lời giải đáp cho những vấn đề trên.

2


CHƢƠNG 1. TỔNG QUAN VỀ MẪU THIẾT KẾ PHẦN MỀM
1.1. Vấn đề trong thiết kế phần mềm hƣớng đối tƣợng
Việc thiết kế phần mềm nói chung và phần mềm hƣớng đối nói riêng là một
việc khó. Thiết kế phần mềm hƣớng đối tƣợng phải đảm bảo giải quyết đƣợc vấn đề
mong muốn, đồng thời phải đảm bảo có thể đƣợc mở rộng trong tƣơng lai mà không
hải thiết kế lại. Tuy nhiên khi thiết kế hƣớng đối tƣợng một phần mềm, không thể đảm
bảo rằng thiết kế đó là đúng và đáp ứng đƣợc các yêu cầu trên. Do đó cần đƣa ra một
vài phƣơng án để từ đó lựa chọn đƣợc phƣơng án tốt nhất. Phƣơng án này đôi khi đƣợc
dùng lại nhiều lần khi gặp các vấn đề tƣơng tự. Ta hay gặp những vấn đề tƣơng tự
nhau đƣợc phát triển thành các mẫu thiết kế, để sử dụng cho các hệ thống phần mềm
ứng dụng.
1.2. Khái niệm Mẫu thiết kế
Mẫu đã tồn tại trong một thời gian dài trong quá trình phát triển phần mềm, tuy

nhiên chƣa có một định nghĩa hoàn thiện cho nó. Mẫu mô tả vấn đề một cách lặp đi lặp
lại và các giải pháp cho vấn đề đó. Nó đƣợc xem nhƣ là một khuôn mẫu đƣợc áp dụng
để giải quyết các trƣờng hợp của cùng một loại vấn đề.
Mẫu thiết kế đƣợc dùng trong công nghệ phần mềm là các giải pháp cho vấn đề
trong thiết kế các hệ thống phần mềm. Đây là tập các giải pháp đã đƣợc công nhận có
giá trị và ngƣời phát triển phần mềm áp dụng để giải quyết các vấn đề tƣơng tự. Cũng
nhƣ trong phân tích và thiết kế hƣớng đối tƣợng, việc sử dụng mẫu thiết kế cần phải
đạt đƣợc khả năng tái sử dụng các giải pháp chuẩn đối với vấn đề xảy ra thƣờng
xuyên.
Christopter Alexander đã định nghĩa [1]: “Mỗi mẫu mô tả một vấn đề mang tính
chất xuất hiện lặp đi lặp lại trong môi trƣờng của chúng ta, một giải pháp cho vấn đề
đó”.
Một định nghĩa khác về mẫu của Gamma [1]: “Một mẫu thể hiện bản chất cốt
lõi của một giải pháp cho một vấn đề xuất hiện lặp đi lặp lại trong một ngữ cảnh đƣợc
chỉ định rõ”.
Mỗi một mẫu mô tả một vấn đề xảy ra lặp đi lặp lại trong môi trƣờng và mô tả
cái cốt lõi của giải pháp để cho vấn đề đó. Bằng cách nào đó bạn đã dùng nó cả triệu
lần mà không làm giống nhau 2 lần.
1.3. Nội dung các mẫu thiết kế GOF [6]
1.3.1. Nhóm mẫu tạo lập
Nhóm gồm có 5 mẫu: AbstractFactory, Abstract Method, Builder, Prototype và
Singleton. Nhóm này liên quan tới việc khởi tạo các thể nghiệm của đối tƣợng, tách
biệt với cách đƣợc thực hiện từ ứng dụng. Xem thông tin của các mẫu trong nhóm dựa
vào biểu đồ phụ thuộc vào mẫu đó, mẫu thiên về hành vi hay cấu trúc.

3


1.3.1.1. Abstract Factory
Trong các hệ điều hành giao diện đồ hoạ, bộ công cụ cung cấp giao diện ngƣời

dùng dựa trên chuẩn xem và cảm nhận (look-and–feel). Có rất nhiều kiểu giao diện
xem và cảm nhận và giao diện ngƣời dùng khác nhau thanh cuộn tài liệu (scroll bar),
cửa sổ (window), nút bấm (button), hộp soạn thảo (editbox), Nếu xem chúng là các
đối tƣợng thì chúng có một số thuộc tính và hành vi khá giống nhau về mặt hình thức
nhƣng lại khác nhau về cách thực hiện. Chẳng hạn đối tƣợng button, window và
editbox có cùng các thuộc tính là chiều dài, rộng, cao, toạ độ,… các phƣơng thức là
Resize(), SetPosition(), Tuy nhiên các đối tƣợng này không thể gộp vào một lớp vì
theo nguyên lý xây dựng lớp, các đối tƣợng thuộc cùng 1 lớp phải có các phƣơng thức
hoạt động nhƣ nhau, trong khi tuy rằng các đối tƣợng ở đây có cùng giao diện nhƣng
cách thực hiện các hành vi lại hoàn toàn khác nhau.
Vấn đề đặt ra là xây dựng một lớp tổng quát, chứa những điểm chung của các
đối tƣợng để từ đó có thể dễ dàng sử dụng lại. Ta gọi lớp này là lớp WidgetFactory.
Các lớp đối tƣợng window, button và editbox thừa kế lớp này. Trong thiết kế hƣớng
đối tƣợng, ta xây dựng mô hình các lớp đó nhƣ sau:

Hình 1.1. Sơ đồ lớp mẫu Abstract Factory
Lớp WidgetFactory có 2 phƣơng thức là CreateScrollBar() và CreateWindow().
Đây là lớp trừu tƣợng tổng quát cho MotifWidgetFactory và PMWidgetFactory. Các
lớp MotifWidgeFactory và PMWidgetFactory thừa kế lớp WidgetFactory. Các nhóm
lớp Window và ScrollBar là các lớp trừu tƣợng. Lớp Window có các lớp con cụ thể là
PMWindow và MotifWindow. Lớp ScrollBar có các lớp con cụ thể là PMScrollBar và
MotifScrollBar. Các đối tƣợng thuộc lớp này đƣợc các đối tƣợng thuộc lớp

4


WidgetFactory (MotifWidgetFactory và PMWidgetFactory) gọi trong các hàm khởi
tạo đối tƣợng. Đối tƣợng client thông qua lớp giao diện của các đối tƣợng
MotifWidgetFactory, PMWidgetFactory, Window và ScrollBar để làm việc với các
đối tƣợng PMWindow, MotifWindow, PMScrollBar,MotifScrollBar. Điều này có thể

thực hiện đƣợc nhờ cơ chế binding trong các ngôn ngữ hỗ trợ lập trình hƣớng đối
tƣợng nhƣ C++, C#, Java, SmallTalk,… Các đối tƣợng PMWindow, MotifWindow,
PMScrollBar, MotifScrollBar đƣợc tạo trong thời gian chạy chƣơng trình nên trình
ứng dụng (đối tƣợng thuộc lớp client) chỉ cần giữ một con trỏ trỏ đến đối tƣợng thuộc
lớp WidgetFactory, và thay đổi địa chỉ con trỏ để có thể làm việc với các đối tƣợng
trên. Các tình huống này thƣờng có cùng một cách giải quyết đã đƣợc chứng tỏ là tối
ƣu. Nó đƣợc tổng quát hoá thành một mẫu thiết kế gọi là AbstractFactory.
Định nghĩa: mẫu Abstract Factory cung cấp cho trình khách một giao diện cho
một tập các đối tƣợng thuộc các lớp khác nhau mà không phải trực tiếp làm việc với
từng lớp con cụ thể.

Hình 1.2. Sơ đồ lớp mẫu Abstract Factory
 AbstractFactory (ContinentFactory): khai báo một giao diện cho các lớp dẫn
xuất cụ thể.

5


 ConcreteFactory (AfricaFactory, AmericaFactory): cài đặt các thao tác để tạo ra
các đối tƣợng dẫn xuất chi tiết.
 AbstractProduct (Herbivore, Carnivore): khai báo một giao diện trừu tƣợng cho
đối tƣợng dẫn xuất.
 Product (Wildebeest, Lion, Bison, Wolf): định nghĩa một đối tƣợng dẫn xuất
đƣợc tạo ra bởi một factory cụ thể tƣơng ứng, cài đặt giao diện AbstractProduct.
 Client (AnimalWorld): sử dụng giao diện đƣợc khai báo bởi các lớp
AbstractFactory và AbstractProduct.
Ví dụ sau đây là các lớp trên đƣợc cài đặt trong C++:
//Cài đặt cho lớp WidgetFactory:
class WidgetFactory{
public:

virtual Window* CreateWindow();
virtual ScrollBar* CreateScrollBar();
};

//Cài đặt cho lớp MotifWidgetFactory và PMWidgeFactory:
class MotifWidgetFactory:public WidgetFactory{
public:
Window* CreateWindow(){
return new MotifWindow();
}
ScrollBar* CreateScrollBar(){
return new MotifScrollBar();
}
};
class PMWidgetFactory:public WidgetFactory{
public:
Window* CreateWindow(){
return new PMWindow();
}
ScrollBar* CreateScrollBar(){
return new PMScrollBar();
}
};

//Lớp đối tượng Window:
class Window{
//định nghĩa các thuộc tính và phương thức.
};
class MotifWindow:public Window{
//định nghĩa các thuộc tính và các phương thức.

};
class PMWindow:public Window{
//định nghĩa các thuộc tính và các phương thức.
};

6



//Các lớp thuộc nhóm ScrollBar.
class ScrollBar{
//định nghĩa các thuộc tính và phương thức.
};
class MotifScrollBar:public ScrollBar{
//định nghĩa các thuộc tính và phương thức.
};
class PMScrollBar:public ScrollBar{
//định nghĩa các thuộc tính và phương thức.
};

//Để truy cập đến các đối tượng này tại chương trình ứng dụng
//ta có thể thực hiện như sau:
class Client{
private:
WidgetFactory* wf;
};
Các mẫu liên quan: AbstractFactory thƣờng đƣợc cài đặt cùng với Singleton,
FactoryMethod và đôi khi cả Prototype. Các lớp con cụ thể thƣờng đƣợc cài đặt bằng
singleton. Bởi singleton có thể tạo ra những đối tƣợng đồng nhất cho dù chúng ta gọi
nó ở đâu đó trong chƣơng trình.

1.3.1.2. Builder
Trong những ứng dụng lớn với các chức năng phức tạp và giao diện đồ sộ, việc
khởi tạo ứng dụng thƣờng gặp nhiều khó khăn. Chúng ta không nên dồn các việc này
cho một hàm khởi tạo, vì nhƣ thế sẽ rất khó kiểm soát và không phải lúc nào các thành
phần của ứng dụng cũng đƣợc khởi tạo một cách đồng bộ. Có thành phần đƣợc tạo lúc
dịch chƣơng trình nhƣng cũng có thành phần tuỳ theo từng yêu cầu của ngƣời dùng,
hoàn cảnh của ứng dụng mà nó sẽ đƣợc tạo ra. Do vậy ngƣời ta giao việc này cho một
đối tƣợng chịu trách nhiêm khởi tạo và chia việc khởi tạo ứng dụng một cách riêng rẽ
để có thể khởi tạo riêng biệt ở các hoàn cảnh khác nhau. Tƣởng tƣợng việc tạo ra đối
tƣợng giống nhƣ tạo ra chiếc xe đạp: đầu tiên tạo ra khung xe, sau đó tạo ra bánh xe,
buđông xe, xích, líp,… Việc tạo ra các bộ phận này không nhất thiết phải đựơc thực
hiện một cách đồng thời hay theo một trật tự nào cả, và cũng có thể đƣợc tạo ra một
cách độc lập bởi nhiều ngƣời. Nhƣng trong một mô hình sản xuất nhƣ vậy, bao giờ
việc tạo ra chiếc xe cũng đƣợc khép kín để tạo ra chiếc xe hoàn chỉnh, đó là nhà máy
sản xuất xe đạp. Ta gọi đối tƣợng nhà máy sản xuất xe đạp này là builder (ngƣời xây
dựng).
Định nghĩa: Builder là mẫu thiết kế chia một công việc khởi tạo phức tạp của
một đối tƣợng thành các công việc riêng rẽ, từ đó có thể tiến hành khởi tạo đối tƣợng ở
các ngữ cảnh khác nhau.

7




Hình 1.3. Sơ đồ lớp mẫu Builder
 Builder (VehicleBuilder): giao diện trừu tƣợng cho việc tạo ra các phần của một
đối tƣợng Product.
 ConcreteBuilder (MotorCycleBuilder, CarBuilder, ScooterBuilder)
 Xây dựng và lắp ráp các phần của dẫn xuất bằng việc cài đặt bổ sung giao

diện Builder.
 Định nghĩa và giữ liên kết đến đại diện mà nó tạo ra.
 Cung cấp một giao diện cho việc gọi dẫn xuất.
 Director (Shop): xây dựng đối tƣợng sử dụng giao diện Builder.
 Product (Vehicle):
 Biểu diễn các đối tƣợng phức tạp. ConcreteBuilder dựng nên các đại diện
bên trong của dẫn xuất và định nghĩa quá trình xử lý bằng các thành phần
lắp ráp của nó.
 Gộp các lớp định nghĩa các bộ phận cấu thành, bao gồm các giao diện
cho việc lắp ráp các bộ phận trong kết quả cuối cùng.
Builder thƣờng đƣợc cài đặt cùng với các mẫu nhƣ Abstract Factory. Abstract
Factory tạo ra một dòng các đối tƣợng dẫn xuất (cả đơn giản và phức tạp). Ngoài ra
Builder còn thƣờng đƣợc cài đặt kèm với Composite pattern. Composite pattern
thƣờng là những gì mà Builder tạo ra.
1.3.1.3. Factory Method
Các Framework thƣờng sử dụng các lớp trừu tƣợng để định nghĩa và duy trì mối
quan hệ giữa các đối tƣợng. Một framework thƣờng đảm nhiệm việc tạo ra các đối
tƣợng hoàn chỉnh. Việc xây dựng một framework cho ứng dụng có thể đại diện cho
nhiều đối tƣợng tài liệu cho ngƣời dùng. Có 2 loại lớp trừu tƣợng chủ chốt trong

8


framework này là lớp ứng dụng và tài liệu. Cả 2 đều là lớp trừu tƣợng, và trình ứng
dụng phải xây dựng các dẫn xuất để tạo ra đối tƣợng phù hợp. Chẳng hạn để tạo ra một
ứng dụng drawing, ta định nghĩa một lớp DrawingApplication và một lớp
DrawingDocument. Lớp ứng dụng chịu trách nhiệm quản lý tài liệu và ta sẽ tạo ra
chúng khi có nhu cầu ( chẳng hạn khi ngƣời dùng chọn Open hoặc New từ menu).
Lớp Document đƣợc tạo ra từ các dẫn xuất của lớp AbstractDocument (trong
framework) để đƣa ra các thể nghiệm cho một ứng dụng Drawing, lớp ứng dụng không

thể biết trƣớc đƣợc lớp dẫn xuất của AbstractDocument nào sẽ đƣợc tạo ra để trình
bày, mà nó chỉ biết khi nào một đối tƣợng tài liệu nào đƣợc tạo. Điều này tạo ra một sự
tiến thoái lƣỡng nan: framework phải thể nghiệm một lớp, nhƣng nó chỉ biết về lớp
trừu tƣợng của nó, mà lớp trừu tƣợng này lại không thể tạo ra thể nghiệm. Nếu làm
việc với giao diện ứng dụng đơn tài liệu và đa tài liệu trong ngôn ngữ Visual C++,
chúng ta sẽ gặp một vấn đề tƣơng tự. Đối tƣợng MainFrame có thể tạo ra một dối
tƣợng view mỗi khi ngƣời dùng nhấn chuột vào menu View hay Open, nhƣng
MainFrame hoàn toàn không biết về View vì nó không chứa bất cứ một thể nghiệm
nào của View.
Mẫu Abstract Method đƣa ra giải pháp cho vấn đề này. Nó đóng gói thông tin
về lớp dẫn xuất Document nào đƣợc tạo ra và đƣa ra ngoài framework.
Lớp dẫn xuất định nghĩa lại một phƣơng thức trừu tƣợng CreateDocument() trên
lớp Application để trả về một đối tƣợng thuộc lớp dẫn xuất của lớp Document.
Class Application{
//Các khai báo khác
public:
Document* CreateDocument();
//Các khai báo khác
};
Document* Application::CreateDocument(){
Document* newDocument = new MyDocument();
Return newDocument;
}
Khi một đối tƣợng thuộc lớp dẫn xuất của Application đƣợc tạo ra, nó có thể tạo
ra các đối tƣợng tài liệu mà không cần biết về các lớp đó. Chúng ta gọi
CreateDocument là một Factory Method bởi vì nhiệm vụ của nó là sản xuất ra các đối
tƣợng.
Định nghĩa: Factory Method là một giao diện cho việc tạo ra một đối tƣợng,
nhƣng để cho lớp dẫn xuất quyết định lớp nào sẽ đƣợc tạo. Factory Method để cho một
lớp trì hoãn sự thể nghiệm một lớp con.


9



Hình 1.4. Sơ đồ lớp mẫu Factory Method
 Product (Page): định nghĩa giao diện của các đối tƣợng mà Factory Method tạo
ra.
 ConcreteProduct (SkillsPage, EducationPage, ExperiencePage): cài đặt giao
diện Product.
 Creator (Document):
 Khai báo Factory Method trả về một đối tƣợng Product. Sự kiến tạo này
cũng có thể định nghĩa một cài đặt mặc định của Factory Method trả về
một đối tƣợng ConcreteProduct mặc định.
 Có thể gọi Factory Method để tạo ra một đối tƣợng Product.
 ConcreteCreator (Report, Resume): chồng lên Factory Method để trả về một thể
nghiệm của một ConcreteProduct.
Abstract Factory thƣờng đƣợc cài đặt cùng với Factory Method. Lớp Factory
Method thƣờng đƣợc gọi là Template Method. Trong ví dụ về ứng dụng Drawing trên,
NewDocument là một template method.
Prototype không cần đến một lớp con Creator, tuy nhiên thƣờng đòi hỏi một
phƣơng thức để tạo thể nghiệm trên lớp dẫn xuất.
1.3.1.4. Prototype
Prototype Pattern giúp cho việc khởi tạo đối tƣợng bằng một đối tƣợng nguyên
mẫu (prototype), là copy của object “mẫu” đó. Ý tƣởng của mẫu là chúng ta đƣợc cung
cấp một đối tƣợng và sẽ dùng đối tƣợng 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 đối tƣợng mới sẽ dựa trên đối tƣợng mẫu
không sử dụng toán tử new hoặc constructor,… đƣợc cụng 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 chi tiết bên trong đối tƣợng và đối tƣợng
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 đối tƣợng cung cấp (vốn

10


không đầy đủ) cho một đối tƣợng mới. Cách tốt nhất là để cho chính đối tƣợng “mẫu”
tự xác định thông tin và dữ liệu sao chép.
Định nghĩa: Prototype là mẫu thiết kế chỉ định ra một đối tƣợng đặc biệt để khởi
tạo, nó sử dụng một thể nghiệm sơ khai rồi sau đó sao chép ra các đối tƣợng khác từ
mẫu đối tƣợng này.

Hình 1.5. Sơ đồ lớp mẫu Prototype
 Prototype: khai báo giao diện cho dòng vô tính của chính nó.
 ConcretePrototype: cài đặt một thao tác cho dòng vô tính của nó.
 Client: tạo ra một đối tƣợng mới bằng việc yêu cầu một nguyên mẫu từ dòng vô
tính của nó
Prototype và Abstract Factory liên quan đến nhau chặt chẽ, có thể đối chọi nhau
theo nhiều kiểu. Tuy nhiên chúng có thể kết hợp cùng nhau. Một Abstract Factory có
thể chứa một tập các Prototype vô tính và trả về các đối tƣợng sản xuất.
1.3.1.5. Singleton
Xét về một đối tƣợng quản lý tài nguyên trong các ứng dụng. Mỗi ứng dụng có
một bộ quản lý tài nguyên, nó cung cấp các điểm truy cập cho các đối tƣợng khác
trong ứng dụng. Các đối tƣợng (khách) có thể lấy ra từ bộ quản lý tài nguyên những gì
chúng cần và thay đổi giá trị bên trong bộ quản lý tài nguyên đó. Để truy cập vào bộ
quản lý tài nguyên, đối tƣợng khách cần phải có một thể nghiệm của bộ quản lý tài
nguyên. Nhƣ vậy trong một ứng dụng sẽ có nhiều thể nghiệm của bộ quản lý tài
nguyên đƣợc tạo ra.
class ResourceManager{

11



private:
int x;
public:
ResourceManager(){x =0; }
void SetX(int _x){ x = _x;}
void GetX(){ return x;}
}
class Client1 {
public:
void DoSomething(){
ResourceManager rm;
printf(“x = %d”,rm.GetX());
x = 100;
}
}
class Client2{
public:
void DoSomething(){
ResourceManager rm;
printf(“x = %d”,rm.GetX());
x = 500;
}
}
Trong ví dụ trên, hàm DoSomething() của Client1 khi truy cập vào đối tƣợng
thuộc lớp ResourceManager sẽ in ra màn hình x = 0 và đặt vào đó x = 100.
Sau đó hàm DoSomething() của Client2 khi truy cập vào đối tƣợng thuộc lớp
ResourceManager sẽ in ra màn hình x = 0 và đặt vào đó x = 500. Rõ ràng là tài nguyên
mà các đối tƣợng khách truy cập vào không thể hiện sự thống nhất. Điều mà lẽ ra khi

giá trị x trong ResourceManager bị Client1 thay đổi thì Client2 phải nhận biết và in ra
màn hình x =100. Nhƣng theo logic cài đặt ở trên thì khi đối tƣợng thuộc lớp Client1
truy cập đến ResourceManager tạo ra một instance và đặt thuộc tính x = 100. Đối
tƣợng Client2 truy cập đến ResourceManager tạo ra một instance và đặt thuộc tính x =
500. Hai instance này độc lập nhau về vùng nhớ, do đó tài nguyên x mà chúng quản lý
cũng là 2 tài nguyên độc lập với nhau. Vấn đề đặt ra là phải tạo ra một bộ quản lý tài
nguyên tạo ra mọi thể nghiệm giống nhau tại nhiều nơi và ở các thời điểm khác nhau.
Singleton cung cấp cho ta cách giải quyết vấn đề này.
Định nghĩa: Singleton là mẫu thiết kế nhằm đảm bảo chỉ có duy nhất một thể
nghiệm và cung cấp điểm truy cập của nó một cách thống nhất toàn cục.


12


Hình 1.6. Sơ đồ lớp mẫu Singleton
Singleton (LoadBalancer)
 Định nghĩa một thao tác tạo thể nghiệm cho phép đối tƣợng khách truy nhập đến
thể nghiệm đồng nhất của nó nhƣ một thao tác của lớp.
 Chịu trách nhiệm về việc tạo ra và duy trì thể nghiệm đồng nhất của chính nó.
Có rất nhiều mẫu có thể cài đặt bổ sung từ việc sử dụng Singleton, chẳng hạn
nhƣ Abstract Factory, Builder, và Prototype.
1.3.2. Nhóm Mẫu cấu trúc
Nhóm gồm có 7 mẫu: Adapter, Bridge, Composite, Decorator, Facade, Proxy và
Flyweight. Nhóm này liên quan tới các quan hệ cấu trúc giữa các thể nghiệm, sử dụng
thừa kế, kết tập và tƣơng tác. Để xem thông tin về mẫu này phải dựa vào biểu đồ lớp
của mẫu.
1.3.2.1. Adapter
Đôi khi một lớp công cụ đƣợc thiết kế cho việc sử dụng lại, lại không thể sử
dụng lại chỉ bởi giao diện không thích hợp với miền giao diện đặc biệt mà một ứng

dụng yêu cầu. Adapter đƣa ra một giải pháp cho vấn đề này.
Trong một trƣờng hợp khác ta muốn sử dụng một lớp đã tồn tại và giao diện của
nó không phù hợp với giao diện của một lớp mà ta yêu cầu.Ta muốn tạo ra một lớp có
khả năng đƣợc dùng lại, lớp đó cho phép kết hợp với các lớp không liên quan hoặc
không đƣợc dự đoán trƣớc, các lớp đó không nhất thiết phải có giao diện tƣơng thích
với nhau.
Định nghĩa: Adapter là mẫu thiết kế dùng để biến đổi giao diện của một lớp
thành một giao diện khác mà clients yêu cầu. Adapter ngăn cản các lớp làm việc cùng
nhau đó không thể làm bằng cách nào khác bởi giao diện không tƣơng thích.

13



Hình 1.7. Sơ đồ lớp mẫu Adapter
 Target: định nghĩa một miền giao diện đặc biệt mà Client sử dụng.
 Client: cộng tác với các đối tƣợng tƣơng thích với giao diện Target.
 Adapter: định nghĩa một giao diện đã tồn tại mà cần phải làm biến đổi cho thích
hợp.
 Adapter: làm tƣơng thích giao diện của Adaptee với giao diện của Target.
Bridge có một cấu trúc tƣơng tự nhƣ một đối tƣợng của Adapter, nhƣng Bridge
có một mục đích khác.Nó chia giao diện từ các phần cài đặt của nó ra riêng rẽ để từ đó
có thể linh hoạt hơn và độc lập nhau. Sử dụng một Adapter đồng nghĩa với việc thay
đổi giao diện của một đối tƣợng đã tồn tại.
Decorator nâng cấp một đối tƣợng khác mà không làm thay đổi giao diện của
nó. Một Decorator do đó mà trong suốt với ứng dụng hơn là một Adapter. Nhƣ một hệ
quả Decorator hỗ trợ cơ chế kết tập đệ quy mà điều này không thể thực hiện đƣợc đối
với các Adapter thuần tuý.
Proxy định nghĩa một đại diện cho một đối tƣợng khác và không làm thay đổi
giao diện của nó.

1.3.2.2. Bridge
Khi một lớp trừu tƣợng (abstraction) có thể có một vài thành phần bổ sung thêm
thì cách thông thƣờng phù hợp với chúng là sử dụng kế thừa. Một lớp trừu tƣợng định
nghĩa một giao diện cho trừu tƣợng đó, và các lớp con cụ thể thực hiện nó theo các
cách khác nhau. Nhƣng cách tiếp cận này không đủ mềm dẻo. Sự kế thừa ràng buộc
một thành phần bổ sung thêm là cố định cho abstraction, điều này làm nó khó thay đổi,

14


mở rộng, và sử dụng lại các Abstraction, các thành phần bổ sung một cách độc
lập.Trong trƣờng hợp này dùng một mẫu Bridge là thích hợp nhất.Mẫu Bridge thƣờng
đƣợc ứng dụng khi :
 Ta muốn tránh một ràng buộc cố định giữa một abstraction và một thành phần
bổ sung thêm của nó.
 Cả hai, các Abstraction và các thành phần cài đặt của chúng nên có khả năng
mở rộng bằng việc phân chia lớp. Trong trƣờng hợp này, Bridge pattern cho
phép ta kết hợp các abstraction và các thành phần bổ sung thêm khác nhau và
mở rộng chúng một cách độc lập.
 Thay đổi trong thành phần đƣợc bổ sung thêm của một abstraction mà không
ảnh hƣởng đối với các client, tức là mã của chúng không nên đem biên dịch lại.
 Ta muốn làm ẩn đi hoàn toàn các thành phần bổ sung thêm của một abstraction
khỏi các client.
 Ta có một sự phát triển rất nhanh các lớp, hệ thống phân cấp lớp chỉ ra là cần
phải tách một đối tƣợng thành hai phần.
 Ta muốn thành phần bổ sung thêm có mặt trong nhiều đối tƣợng, và việc này lại
đƣợc che khỏi client (client không thấy đƣợc).
Định nghĩa: Bridge là mẫu thiết kế dùng để tách riêng một lớp trừu tƣợng khỏi
thành phần cài đặt của nó để có đƣợc hai cái có thể biến đổi độc lập.



Hình 1.8. Sơ đồ lớp mẫu Bridge

15


 Abstraction (BusinessObject)
 Định nghĩa một giao diện trừu tƣợng
 Duy trì một tham chiếu tới đối tƣợng của các lớp kế thừa từ nó
 RefinedAbstraction (CustomersBusinessObject): mở rộng giao diện bằng cách
định nghĩa một đối tƣợng trừu tƣợng
 Implementor (DataObject): định nghĩa giao diện cho lớp kế thừa.Giao diện này
không phải tƣơng ứng chính xác với giao diện trừu tƣợng. Trong thực tế 2 giao
diện này có thể khá là độc lập. Việc kế thừa một cách tuỳ ý các giao diện cũng
chỉ cung cấp duy nhất các thao tác nguyên thuỷ và lớp trừu tƣợng định nghĩa
một thao tác mức trên dựa những thao tác nguyên thuỷ này.
 ConcreteImplementor (CustomersDataObject): cài đặt giao diện đã đƣợc cài đặt
và định nghĩa một cài đặt cụ thể.
Abstract Factory cũng có thể tạo ra và cấu hình một Bridge. Adapter có thể
đƣợc cơ cấu theo hƣớng để 2 lớp không có quan hệ gì với nhau có thể làm việc với
nhau đƣợc. Nó thƣờng ứng dụng cho các hệ thống sau khi đã đƣợc thiết kế. Bridge xét
ở một khía cạnh khác nó kết thúc một thiết kế để lớp trừu tƣợng và lớp cài đặt có thể
tuỳ biến một cách độc lập.
1.3.2.3. Composite
Các ứng dụng đồ họa nhƣ bộ soạn thảo hình vẽ và các hệ thống lƣu giữ biểu đồ
cho phép ngƣời sử dụng xây dựng lên các lƣợc đồ phức tạp khác xa với các thành phần
cơ bản, đơn giản. Ngƣời sử dụng có thể nhóm một số các thành phần để tạo thành các
thành phần khác lớn hơn, và các thành phần lớn hơn này lại có thể đƣợc nhóm lại để
tạo thành các thành phần lớn hơn nữa. Một cài đặt đơn giản có thể xác định các lớp
cho các thành phần đồ họa cơ bản nhƣ Text và Line, cộng với các lớp khác cho phép

hoạt động nhƣ các khuôn chứa các thành phần cơ bản đó.
Nhƣng có một vấn đề với cách tiếp cận này, đó là, mã sử dụng các lớp đó phải
tác động lên các đối tƣợng nguyên thủy (cơ bản) và các đối tƣợng bao hàm các thành
phần nguyên thủy ấy là khác nhau ngay cả khi hầu hết thời gian ngƣời sử dụng tác
động lên chúng là nhƣ nhau. Có sự phân biệt các đối tƣợng này làm cho ứng dụng trở
nên phức tạp hơn. Composite pattern đề cập đến việc sử dụng các thành phần đệ quy
để làm cho các client không tạo ra sự phân biệt trên.
Giải pháp của Composite pattern là một lớp trừu tƣợng biểu diễn cả các thành
phần cơ bản và các lớp chứa chúng. Lớp này cũng xác định các thao tác truy nhập và
quản lý các con của nó.
Ví dụ

16



Hình 1.9. Sơ đồ lớp minh họa

Hình 1.10. Sơ đồ phân cấp
Composite đƣợc áp dụng trong các trƣờng hợp sau :
 Ta muốn biểu diễn hệ thống phân lớp bộ phận – toàn bộ của các đối tƣợng
 Ta muốn các client có khả năng bỏ qua sự khác nhau giữa các thành phần của
các đối tƣợng và các đối tƣợng riêng lẻ. Các client sẽ “đối xử” với các đối tƣợng
trong cấu trúc composite một cách thống nhất.
Định nghĩa: Composite là mẫu thiết kế dùng để tạo ra các đối tƣợng trong các
cấu trúc cây để biểu diễn hệ thống phân lớp: bộ phận – toàn bộ. Composite cho phép
các client tác động đến từng đối tƣợng và các thành phần của đối tƣợng một cách
thống nhất.

17





Hình 1.11. Sơ đồ lớp mẫu Composite
 Component (DrawingElement)
 Khai báo giao diện cho các đối tƣợng trong một khối kết tập.
 Cài đặt các phƣơng thức mặc định cho giao diện chung của các lớp một
cách phù hợp.
 Khai báo một giao diện cho việc truy cập và quản lý các thành phần con
của nó
 Định nghĩa một giao diện cho việc truy cập các đối tƣợng cha của các
thành phần theo một cấu trúc đệ quy và cài đặt nó một cách phù hợp nhất.
 Leaf (PrimitiveElement)
 Đại diện cho một đối tƣợng nút là trong khối kết tập. Một lá là một nút
không có con.
 Định nghĩa hành vi cho các đối tƣợng nguyên thuỷ trong khối kết tập
 Composite (CompositeElement)
 Định nghĩa hành vi cho các thành phần mà có con.
 Lƣu trữ các thành phần con
 Cài đặt toán tử quan hệ giữa các con trong giao diên của thành phần
 Client (CompositeApp): vận dụng các đối tƣợng trong khối kết tập thông qua
giao diện của thành phần

18


Một mẫu mà thƣờng dùng làm thành phần liên kết đến đối tƣợng cha là Chain of
Responsibility
Mẫu Decorator cũng thƣờng đƣợc sử dụng với Composite.Khi Decorator và

Composite cùng đƣợc sử dụng cùng nhau, chúng thƣờng sẽ có một lớp cha chung. Vì
vậy Decorator sẽ hỗ trợ thành phần giao diện với các phƣơng thức nhƣ Add, Remove
và GetChild.
Mẫu Flyweight để cho chúng ta chia sẻ thành phần, nhƣng chúng sẽ không tham
chiếu đến cha của chúng.
Mẫu Iterator có thể dùng để duyệt mẫu Composite.
Mẫu Visitor định vị thao tác và hành vi nào sẽ đƣợc phân phối qua các lớp lá và
Composite.
1.3.2.4. Decorator
Định nghĩa:gắn một vài chức năng bổ sung cho các đối tƣợng (gán động).
Decorator cung cấp một số thay đổi mềm dẻo cho các phân lớp để mở rộng thêm các
chức năng.
Sử dụng Decorator khi:
 Thêm các chức năng bổ sung cho các đối tƣợng riêng biệt một cách động và
trong suốt, nghĩa là không chịu ảnh hƣởng (tác động ) của các đối tƣợng khác.
 Cho các chức năng mà các chức năng này có thể đƣợc rút lại (hủy bỏ) (nếu
không cần nữa).
 Khi sự mở rộng đƣợc thực hiện bởi các phân lớp là không thể thực hiện đƣợc.
Đôi khi một lƣợng lớn các mở rộng độc lập có thể thực hiện đƣợc nhƣng lại tạo
ra một sự bùng nổ các phân lớp để trợ giúp cho các kết hợp. Hoặc một định
nghĩa lớp có thể bị che đi hay nói cách khác nó không có giá trị cho việc phân
lớp.

×