Tải bản đầy đủ (.docx) (53 trang)

Mẫu thiết kế an toàn trong lập trình ứ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 (759.51 KB, 53 trang )

BAN CƠ YẾU CHÍNH PHỦ
HỌC VIỆN KỸ THUẬT MẬT MÃ
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯

ĐỒ ÁN TỐT NGHIỆP
NGHIÊN CỨU CÁC MẪU THIẾT KẾ PHẦN MỀM AN TOÀN

Ngành: Công nghệ thông tin
Chuyên ngành: An toàn thông tin
Mã số: 52.48.02.01

Hà Nội, 2016


BAN CƠ YẾU CHÍNH PHỦ
HỌC VIỆN KỸ THUẬT MẬT MÃ
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯

ĐỒ ÁN TỐT NGHIỆP
NGHIÊN CỨU CÁC MẪU THIẾT KẾ PHẦN MỀM AN TOÀN

Ngành: Công nghệ thông tin
Chuyên ngành: An toàn thông tin
Mã số: 52.48.02.01

Sinh viên thực hiện:
NGUYỄN NGỌC ÁNH
Lớp: AT8B
Người hướng dẫn 1:
THS. LÊ BÁ CƯỜNG
Khoa Công nghệ thông tin – Học viện Kỹ thuật mật mã



Hà Nội, 2016

NGUYỄN NGỌC ÁNH-AT8B

2


LỜI CẢM ƠN
Lời đầu tiên, em xin được chân thành cảm ơn Học viện Kỹ Thuật Mật Mã
đã cho em một môi trường học tập và rèn luyện thuận lợi. Cảm ơn Khoa An
Toàn Thông Tin - Học Viện Kỹ Thuật Mật Mã đã tạo điều kiện tốt cho em thực
hiện Đồ án tốt nghiệp này. Em xin chân thành cảm ơn quí Thầy Cô trong Học
viện đã tận tình giảng dạy, trang bị cho em những kiến thức quí báu trong những
năm học vừa qua.
Em xin gửi lời cảm ơn đặc biệt tới Ths. Lê Bá Cường –giảng viên khoa
CNTT Học Viện Kỹ Thuật Mật Mã đã tận tình hướng dẫn, chỉ bảo em trong suốt
thời gian thực hiện đề tài.
Xin chân thành cảm ơn các anh chị và bạn bè đã ủng hộ, giúp đỡ và động
viên tôi trong thời gian học tập và nghiên cứu.
Mặc dù em đã cố gắng hoàn thành Đồ án trong phạm vi và khả năng cho
phép nhưng chắc chắn sẽ không tránh khỏi những thiếu sót. Em kính mong nhận
được sự cảm thông và góp ý tận tình của quí Thầy Cô và các bạn.
Em xin chân thành cảm ơn!

Hà Nội, Ngày 10 tháng 06 năm 2016
Sinh viên thực hiện:
Nguyễn Ngọc Ánh.

NGUYỄN NGỌC ÁNH-AT8B


3


MỤC LỤC

NGUYỄN NGỌC ÁNH-AT8B

4


DANH MỤC HÌNH ẢNH

NGUYỄN NGỌC ÁNH-AT8B

5


DANH MỤC BẢNG

NGUYỄN NGỌC ÁNH-AT8B

6


DANH MỤC TỪ VIẾT TẮT
Từ viết tắt
NFR
OLTP
RBAC


NGUYỄN NGỌC ÁNH-AT8B

Từ đầy đủ
Non- Functional Requirement
Online Tenure and Promotion System
Role- Base Access Control

7


LỜI NÓI ĐẦU
Công nghệ phần mềm hiện nay là ngành có đóng góp rất lớn cho sự phát
triển của xã hội, rất nhiều công ty phần mềm và sản phẩm phần mềm ra đời
nhằm đáp ứng mọi nhu cầu tin học hóa của các tổ chức và cá nhân. Tuy nhiên,
những báo cáo về tình hình bảo mật hiện nay đối với các hệ thống phần mềm
cho thấy một sự thiếu hụt về nhận thức trong phát triển. Phần mềm hiện nay
thường thiếu tính an toàn và có nhiều lỗ hổng tạo cơ hội cho những kẻ tấn công
bất hợp pháp. Nguyên nhân cốt lõi của vấn đề này là do các nhà phát triển phần
mềm thường chỉ chú ý đến các yêu cầu chức năng mà hệ thống cần đáp ứng và
hầu như bỏ qua các yêu cầu phi chức năng khác trong đó có yêu cầu về bảo mật.
Trong khi các nghiên cứu đã chỉ ra rằng một lỗi sẽ được kiểm soát và sửa
chữa tốt hơn và mất ít chi phí hơn khi nó được phát hiện từ sớm thì các vấn đề
bảo mật luôn được đặt ra sau cùng khi hầu như toàn bộ phần mềm đã được xây
dựng xong. Vấn đề bảo mật lúc đó được thực hiện bằng cách bồi đắp thêm
những thành phần hoặc chính sách bảo mật bởi riêng các kỹ sư bảo mật. Tuy
nhiên, cách làm này thường không bao quát được hết các yêu cầu về bảo mật và
có thể tạo ra sự xung đột với các thành phần chức năng đã được xây dựng sẵn
trong hệ thống và có thể tạo ra những lỗi bảo mật nghiêm trọng hơn. Vậy nhu
cầu tất yếu là cần phải tích hợp bảo mật vào quá trình phát triển phần mềm ngay

từ những pha đầu tiên nhằm tạo ra một phần mềm an toàn.
Trong phát triển phần mềm, các nhà nghiên cứu thường mắc phải các lỗi
khi xây dựng. Vì vậy, họ đã đúc rút kinh nghiệm để xây dựng các mẫu thiết kế
an toàn trong hệ thồng.
Bố cục gồm 3 chương chính
Chương I: Tổng quan về mẫu thiết kế, trong chương này trình bày các khái niệm
cơ bản, lịch sử phát triển, vai trò… của mẫu thiết kế. Các mẫu thiết kế phần
mềm cơ bản sẽ được trình bày trong chương 2
NGUYỄN NGỌC ÁNH-AT8B

8


Chương II: Hệ thống các mẫu thiết kế, bao gồm 23 mẫu thiết kế và tìm hiểu một
số mẫu thiết kế phổ biến.
Chương III: Nghiên cứu các mẫu thiết kế trong phát triển phần mềm an toàn.
Chương này trình bày về tính an toàn của NFRs, một số mẫu thiết kế phần mềm
an toàn và một số ví dụáp dụng mô hình an toàn vào thực tế.

NGUYỄN NGỌC ÁNH-AT8B

9


CHƯƠNG I: TỔNG QUAN VỀ MẪU THIẾT KẾ
1.1. Lịch sử phát triển của mẫu thiết kế (Design pattern)
Ý tưởng dùng mẫu xuất phát từ ngành kiến trúc[5], 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 dữ 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. Mẫu được xem là đạt chuẩn
về an toàn để có thể áp dụng vào các hệ thống một cách đúng đắn.
Suốt những năm đầu 1990, thiết kế mẫu đượ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 dữ 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ướng đố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 Language of Programming Design)
đã được tổ chức. Cũng trong năm này quyển sách Design patterns: Elements of
Reusable Object Oriented Software (Gamma, Johnson, Helm và 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.
Design pattern là thuật ngữ được đưa ra năm 1995 bởi Gang of Four
(GoF) và đã tạo nên một cuộc cách mạng trong phát triển phần mềm. Hiểu một
cách phi hình thức, một design pattern là một cặp vấn đề/giải pháp cho những
bài toán thiết kế được lặp đi lặp lại trong một ngữ cảnh nhất định. Một design
NGUYỄN NGỌC ÁNH-AT8B


10


pattern có bốn đặc trưng cơ bản là: problem, context,solution và consequences
làm nền tảng để cấu trúc hóa các tài liệu đặc tả chúng. Sức mạnh của design
pattern nằm ở chỗ nó là sự kết tinh tri thức và kinh nghiệm của các chuyên gia
trong lĩnh vực thiết kế: dùng một design pattern, ta không chỉ dùng chính bản
thân pattern đó mà thực chất ta đã sử dụng chính tri thức và nhiều năm kinh
nghiệm của các chuyên gia. Đồng thời, việc phổ biến design pattern cũng tạo
nên một ngôn ngữ chung về thiết kế, tạo thuận lợi cho việc trao đổi giữa các
chuyên gia trong lĩnh vực này. Sau khi ra đời, design pattern đã tạo cảm hứng
có các tác giả khác và kết quả là các khái niệm liên quan đã ra đời như analysis
patterns, specification patterns và security patterns.
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ó năm 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ọ đang thiế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.
1.2. Khái niệm
Design Patterns[3] là các mẫu thiết kế được các lập trình viên sử dụng
rộng rãi. Mỗi mẫu "Design Patterns" là một giải pháp giải quyết tốt cho các lập
trình viên khi ở trường hợp nhất định. Để có thể làm giảm rủi ro, thời gian và
công sức thì design pattern sẽ là ý tưởng tốt khi sử dụng.
Một mẫu thiết kế là một cặp (vấn đề, lời giải) có thể áp dụng trong nhiều
tình huống ngữ cảnh khác nhau. Mỗi mẫu thường bao gồm các bộ phận: tên, nội
dung, vấn đề, lời giải (phải đủ tổng quát để có thể dùng trong nhiều tình huống),

các hệ quả mang lại và ví dụ áp dụng.
Design patterns là tập các giải pháp cho vấn đề phổ biến trong thiết kế các
hệ thống máy tính. Đây là tập các giải pháp đã được công nhận là tài liệu có giá
trị, những người phát triển có thể áp dụng giải pháp này để giải quyết các vấn đề
tương tự.
Giống như với các yêu cầu của thiết kế và phân tích hướng đối tượng
(nhằm đạt được khả năng sử dụng các thành phần và thư viện lớp), việc sử dụng
NGUYỄN NGỌC ÁNH-AT8B

11


các mẫu cũng 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 đề thường xuyên xảy ra. Christopher Alexander nói rằng :” 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 hai lần”.
1.3. Vai trò mẫu thiết kế
Design pattern[5] là cách duy nhất để chuyển hóa một cách chính xác các
yêu cầu của khách hàng thành mô hình thiết kế hệ thống phần mềm cuối cùng,
làm cơ sở cho việc triển khai chương trình phần mềm.
Mẫu thiết kế là công cụ giao tiếp giữa các nhóm cùng tham gia phát triển
sản phẩm, quản lý rủi ro, đạt được phần mềm hiệu quả.
Không những vậy, Design pattern còn là tài liệu cung cấp đầy đủ các
thông tin cần thiết để bảo trì hệ thống. Nếu không có thiết kế thì hệ thống không
tin cậy, vì vậy có nguy cơ thất bại rất cao. Một thiết kế tốt là chìa khóa làm cho
phần mềm hữu hiệu.
1.4. Ứng dụng của mẫu thiết kế
Design pattern giúp tăng tốc độ phát triển phần mềm bằng cách đưa ra các
mô hình test, mô hình phát triển đã qua kiểm nghiệm. Thiết kế phần mềm hiệu

quả đòi hỏi phải cân nhắc các vấn đề sẽ nảy sinh trong quá trình hiện thực hóa.
Dùng lại các design pattern giúp tránh được các vấn đề tiềm ẩn có thể gây ra
những lỗi lớn, đồng thời giúp code dễ đọc hơn.
Thông thường, chúng ta chỉ biết áp dụng một kĩ thuật thiết kế nhất định để
giải quyết một bài toán nhất định. Các kĩ thuật này rất khó áp dụng với các vấn
đề trong phạm vi rộng hơn. Design pattern cung cấp giải pháp ở dạng tổng quát.
Hệ thống các mẫu design pattern hiện có 23 mẫu được định nghĩa trong
cuốn “Design patterns Elements of Reusable Object Oriented Software”. Hệ
thống các mẫu này có thể đủ và tối ưu cho việc giải quyết hết các vấn đề của bài
toán phân tích thiết kế và xây dựng phần mềm trong thời điểm hiện tại.

NGUYỄN NGỌC ÁNH-AT8B

12


CHƯƠNG II: HỆ THỐNG CÁC MẪU THIẾT KẾ
Hiện nay, Design pattern được chia thành 3 loại chính[7]:


Mẫu thiết kế khởi tạo (Creational Pattern): Factory, Abstract Factory, Singleton,
Prototype, Builder. Nhóm này liên quan tới việc tạo ra các thể nhiệm (instance)
của đối tượng, tách biệt với cách được thực hiện từ ứng dụng. Muốn xem xét
thông tin của các mẫu trong nhóm này thì phải dựa vào biểu đồ nào phụ thuộc
vào chính mẫu đó, mẫu thiên về hành vi hay cấu trúc.



Mẫu thiết kế cấu trúc (Structural Pattern): Gồm Proxy, Adapter, Wrapper,
Bridge, Facade...... .Nhóm này liên quan tới các quan hệ cấu trúc giữa các thể

nghiệm, dùng kế thừa, kết tập, 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.



Mẫu thiết kế hành vi ( Behavioral Pattern): Gồm Observer, State,
Command....Nhóm này liên quan đến các quan hệ gán trách nhiệm để cung cấp
các chức năng giữa các đối tượng trong hệ thống. Đối với các mẫu thuộc nhóm
này ta có thể dựa vào biểu đồ cộng tác và biểu đồ diễn tiến. Biểu đồ cộng tác và
biểu đồ diễn tiến sẽ giải thích cho ta cách chuyển giao của các chức năng.
Bảng 1.1: Bảng thống kê các mẫu thiết kế
ST

Tên

Mục đích

T
1

Abstract

Mẫu khởi tạo (Creational Pattern)
Cung cấp một interface cho việc tạo lập các đối tượng

Factory

(có liên hệ với nhau) mà không cần qui định lớp khi hay
xác định lớp cụ thể (concrete) tạo mỗi đối tượng


2

Builder

Tần suất sử dụng: cao
Tách rời việc xây dựng (construction) 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.

3

Factory

Tần suất sử dụng: trung bình thấp
Định nghĩa Interface để sinh ra đối tượng nhưng để cho

Method

lớp con quyết định lớp nào được dùng để sinh ra đối
tượng Factory method cho phép một lớp chuyển quá

NGUYỄN NGỌC ÁNH-AT8B

13


trình khởi tạo đối tượng cho lớp con.
4

Prototype


Tần suất sử dụng: cao
Quy đị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.

5

Singleton

Tần suất sử dụng: trung bình
Đả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ó.

6

Adapter

Tần suất sử dụng: cao trung bình
Mẫu thiết kế cấu trúc (Structural Pattern)
Do vấn đề tương thích, thay đổi interface của một lớp
thành một interface khác phù hợp với yêu cầu người sử
dụng lớp.

7

Bridge

Tần suất sử dụng: cao trung bình
Tách rời ngữ nghĩa của một vấn đề khỏi việc cài đặt,

mục đích để cả hai bộ phận (ngữ nghĩa và cài đặt) có thể
thay đổi độc lập nhau.

8

Composite

Tần suất sử dụng: trung bình
Tổ chức các đối tượng theo cấu trúc phân cấp dạng cây.
Tất cả 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.
Tạo quan hệ thứ bậc bao gộp giữa các đối tượng. Client
có thể xem đối tượng bao gộp và bị bao gộp như nhau ->
khả năng tổng quát hoá trong code của client -> dễ phát
triển, nâng cấp, bảo trì.

9

Decorator

Tần suất sử dụng: cao trung bình
Gán thêm trách nhiệm cho đối tượng (mở rộng chức
năng) vào lúc chạy (dynamically).

10

Facade

Tần suất sử dụng: trung bình
Cung cấp một interface thuần nhất cho một tập hợp các

interface trong một “hệ thống con” (subsystem). Nó định
nghĩa một interface cao hơn các interface có sẵn để làm

NGUYỄN NGỌC ÁNH-AT8B

14


cho hệ thống con dễ sử dụng hơn.
11

Flyweight

Tần suất sử dụng: cao
Sử dụng việc chia sẻ để thao tác hiệu quả trên một số
lượng lớn đối tượng “cỡ nhỏ” (chẳng hạn paragraph,
dòng, cột, ký tự…).

12

Proxy

Tần suất sử dụng: thấp
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 đối tượng đó.
Đối tượng thay thế gọi là proxy.

13

Chain


Tần suất sử dụng: cao trung bình
Mẫu thiết kế hành vi (Behavioral Pattern)
of Khắc phục việc ghép cặp giữa bộ gửi và bộ nhận thông

Responsibility điệp. Các đối tượng nhận thông điệp được kết nối thành
một chuỗi và thông điệp được chuyển dọc theo chuỗi
này đến khi gặp được đối tượng xử lý nó.Tránh việc gắn
kết cứng giữa phần tử gửi request với phần tử nhận và
xử lý request bằng cách cho phép hơn một đối tượng có
cơ hội xử lý request . Liên kết các đối tượng nhận
request thành 1 dây chuyền rồi “pass” request xuyên qua
từng đối tượng xử lý đến khi gặp đối tượng xử lý cụ thể.
14

Command

Tần suất sử dụng: trung bình thấp
Mỗi yêu cầu (thực hiện một thao tác nào đó) được bao
bọc thành một đối tượng. Các yêu cầu sẽ được lưu trữ và
gửi đi như các đối tượng. Đóng gói request vào trong
một Object , nhờ đó có thể thông số hoá chương trình
nhận request và thực hiện các thao tác trên request: sắp
xếp, log, undo…

15

Interpreter

Tần suất sử dụng: cao trung bình

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ữ.

16

Iterator

Tần suất sử dụng: thấp
Truy xuất các phần tử của đối tượng dạng tập hợp tuần

NGUYỄN NGỌC ÁNH-AT8B

15


tự (list, array, …) mà không phụ thuộc vào biểu diễn bên
17

Mediator

trong của các phần tử. Tần suất sử dụng: cao
Định nghĩa một đối tượng để bao bọc việc giao tiếp giữa
một số đối tượng với nhau.

18

Memento

Tần suất sử dụng: trung bình thấp
Hiệu chỉnh và trả lại như cũ trạng thái bên trong của đối

tượng mà vẫn không vi phạm việc bao bọc dữ liệu.

19

Observer

Tần suất sử dụng: thấp
Đị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.

20

State

Tần suất sử dụng: cao
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 , ta có cảm giác như class của
đối tượng bị thay đổi.

21

Strategy

Tần suất sử dụng: trung bình
Bao bọc một họ các thuật toán bằng các lớp đối tượng để
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.


22

Visitor

Tần suất sử dụng: cao trung bình
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 đó.

23

Template

Tần suất sử dụng: thấp
Định nghĩa phần khung của một thuật toán, tức là một

method

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.
Tần suất sử dụng: trung bình

Dưới đây là nội dung chi tiết một số mẫu thiết kế nổi bật
NGUYỄN NGỌC ÁNH-AT8B

16



2.1 Mẫu thiết kế khởi tạo
2.1.1: Mẫu Singleton
2.1.1.1: Định nghĩa
Mẫu Singleton[7] được dùng trong trường hợp khi chúng ta muốn chỉ
khởi tạo duy nhất một đối tượng của một lớp và cho phép nhiều người dùng đối
tượng đó. Đôi khi trong vòng đời của ứng dụng, chúng ta chỉ cần một thể hiện
của một lớp, chẳng hạn như chúng ta chỉ cần một đối tượng kết nối database
trong một ứng dụng. Trong trường hợp này, mẫu Singleton thực sự hữu ích bởi
vì nó đảm bảo rằng chỉ tồn tại một và chỉ một instance của một đối tượng cụ thể
nào đó. Hơn nữa, nó còn cho thấy các đối tượng client có thể truy cập vào
instance này một cách nhất quán. Bên cạnh đó, nó ngăn cản các đối tượng client
tạo ra các instance mới từ lớp đó.
2.1.1.2: Mục đích



Tạo ra một instance của một lớp.
Cung cấp một điểm truy cập global vào đối tượng.

2.1.1.3: Lược đồ UML

Hình 1.1: Lược đồ UML của mẫu Singleton
Trong đó:

NGUYỄN NGỌC ÁNH-AT8B

17


Singleton: cung cấp một Constructor private, duy trì một tham chiếu private

static đến instance đơn của lớp, đồng thời nó cung cấp phương thức static để trả
về một tham chiếu đến instance đơn đó.
2.1.1.4: Lợi ích và hạn chế
• Singleton là lớp chỉ có thể tạo ra một instance của chính nó. Bạn không

thể tạo ra nó mà không dùng phương thức static được cung cấp.
• Bạn không cần phải gán tham chiếu cho tất cả các đối tượng cần

Singleton này.
• Tuy nhiên, mẫu Singleton cũng có thể gặp vấn đề với thread, và nó phụ

thuộc vào phần thực thi(hay cài đặt). Bạn phải cẩn thận trong các ứng
dụng multithread, nếu không có cơ chế kiểm soát thích hợp, rất có thể sẽ
xảy ra xung đột giữa các thread.
2.1.1.5: Các biến thể của Singleton
Có nhiều instance trong Singleton. Lợi ích ở đây là phần còn lại của ứng
dụng vẫn như cũ, trong khi các instance khác được sử dụng các phương thức
khác để nhận các instance khác.
Nếu Singleton thực thi giao diện Serializable, thì chúng phải thực thi
phương thức readResolve() để tránh tạo ra 2 đối tượng khác nhau.
2.1.2: Mẫu Abstract factory
2.1.2.1: Giới thiệu
Mô-đun hóa là một vấn đề lớn trong lập trình hiện nay. Lập trình viên trên
toàn thế giới đang cố gắng tránh những ý tưởng về việc thêm mã vào các lớp đã
được xây dựng để làm cho chúng đóng gói hỗ trợ thêm thông tin chung. Lấy ví
dụ về trường hợp của một người quản lý thông tin, ở đây là quản lý các số điện
thoại. Số điện thoại có một quy tắc cụ thể mà chúng được tạo ra tùy thuộc vào
các vùng miền và quốc gia. Nếu tại một số thời điểm, ứng dụng nhận yêu cầu
thay đổi để hỗ trợ thêm mẫu số điện thoại mới của một quốc gia mới, các mã của
ứng dụng sẽ phải được thay đổi và lúc đó, mọi việc sẽ càng trở nên phức tạp

hơn.
NGUYỄN NGỌC ÁNH-AT8B

18


Để giải quyết vấn đề này, mẫu thiết kế Abstract Factory được sử dụng. Sử
dụng mẫu thiết kế này, nó sản sinh ra các đối tượng tuân theo một mẫu chung và
tại thời điểm runtime, factory này sẽ kết hợp với bất kỳ factory cụ thể nào để sản
sinh ra các đối tượng đúng với mẫu của một quốc gia nhất định. Nói cách khác,
Abstract Factory là super-factory để sản xuất ra các factory khác ( Factory of
factories).
2.1.2.2: Định nghĩa
Abstract Factory[7] cung cấp giao diện để tạo ra một họ(family) các đối
tượng có liên quan với nhau, mà không cần phải chỉ rõ các lớp một cách tường
minh.
2.1.2.3: Lược đồ UML
Về cơ bản, Abstract Factory hoạt động như mô hình dưới đây:

Hình 1.2: Lược đồ UML của mẫu AbstractFactory
Các lớp tham gia vào mẫu Abstract Factory này là:
• AbstractFactory – là một lớp abstract hay một interface cho các hoạt động

tạo ra các sản phẩm abstract.
• ConcreteFactory – implement các hoạt động để tạo ra các sản phẩm cụ thể.
• AbstractProduct – là một lớp abstract hay một interface mô tả các hành xử

chung của tài nguyên được sử dụng bởi ứng dụng.
NGUYỄN NGỌC ÁNH-AT8B


19


• Product - định nghĩa một sản phẩm được tạo ra cho phù hợp với

ConcreteFactory. Nó implement abstract hay interface AbstractProduct.
• Client - sử dụng các interface khai báo bởi các lớp AbstractFactory và

AbstractProduct
Lớp AbstractFactory là lớp xác định kiểu đối tượng cụ thể trong thực tế và
tạo ra nó, nhưng nó trả về một abstract trỏ đến đối tượng cụ thể vừa tạo. Điều
này sẽ xác định hành vi của client mà yêu cầu các factory để tạo ra một đối
tượng của một loại trừu tượng nhất định và trả về abstract trỏ đến nó.
2.1.2.4: Lợi ích và hạn chế
Abstract Factory làm tăng tính linh hoạt chung của một ứng dụng. Sự linh
hoạt này thể hiện trong thời gian thiết kế và thời gian chạy. Trong quá trình thiết
kế, bạn không có để dự đoán những vấn đề sẽ phát sinh trong tương lai, và thay
vào đó, bạn tạo một framework chung và sau đó phát triển thực thi một cách độc
lập với phần còn lại của ứng dụng. Khi chạy, các ứng dụng có thể dễ dàng tích
hợp các tính năng mới và tài nguyên.
Để nhận ra lợi ích của pattern này, bạn nên thận trọng trong việc định
nghĩa một giao diện chung phù hợp cho abstract product. Nếu abstract product
không đúng quy định thì sẽ sản sinh ra các concrete product không theo ý muốn.
2.1.2.5: Các biến thể của Abstract Factory
Như đã đề cập ở trên, bạn có thể định nghĩa AbstractFactory và
AbstractProduct hoặc là abstract class hay là một interface, tùy thuộc vào nhu
cầu ứng dụng và sở thích của bạn.
Tùy thuộc vào cách mà factory được sử dụng, có một vài biến thể của
pattern này cho phép tạo ra nhiều đối tượng ConcreteFactory, và kết quả là có
thể sử dụng nhiều đồng thời nhiều họ ConcreteProduct.

2.1.3: Mẫu Builder
2.1.3.1: Giới thiệu

NGUYỄN NGỌC ÁNH-AT8B

20


Một ứng dụng ngày càng phức tạp hơn bởi các lớp và các đối tượng sử
dụng tăng lên. Một ứng dụng có thể cần một cơ chế cho việc xây dựng các đối
tượng phức tạp độc lập với cái tạo nên các đối tượng. Nếu đây là vấn đề mà bạn
đang gặp phải, bạn nên sử dụng các mẫu thiết kế Builder (hoặc Adaptive
Builder).
Mô hình này có liên quan với việc xây dựng một đối tượng phức tạp từ
nhiều nguồn khác nhau, nên nó được gọi là Builder. Khi đối tượng tạo ra ngày
càng phức tạp, quản lý đối tượng tạo ra từ bên trong bộ khởi dựng Contructor có
thể trở nên khó khăn. Điều này đặc biệt đúng nếu đối tượng không phụ thuộc
hoàn toàn vào nguồn tài nguyên mà nằm bên dưới điều khiển của nó.
Các đối tượng ở mức tác nghiệp(business) thường rơi vào loại này. Chúng
thường yêu cầu dữ liệu từ database để khởi tạo và có thể cần kết hợp với một số
đối tượng business khác để trình bày chính xác mô hình business.
Trong những trường hợp như thế, nó rất thuận tiện để định nghĩa một lớp
(Builder) khác có trách nhiệm xây dựng. Builder sắp xếp dây chuyền các đối
tượng sản phẩm: tạo ra các tài nguyên, lưu trữ kết quả trung gian, và cung cấp
các cấu trúc chức năng cho việc tạo lập. Ngoài ra, các Builder có thể có được tài
nguyên hệ thống yêu cầu cho việc xây dựng các đối tượng sản phẩm.
2.1.3.2: Khái niệm
Builder[7] 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

2.1.3.3: Mục đích
 Xác định một thể hiện cho việc tạo ra một đối tượng mà để cho các lớp

con của nó quyết định việc thể hiện.
 Tham chiếu đến đối tượng mới được tạo ra thông qua giao diện chung.

2.1.3.4: Lược đồ UML
Về cơ bản, Builder hoạt động như sơ đồ dưới đây:

NGUYỄN NGỌC ÁNH-AT8B

21


Hình 1.3: Lược đồ UML của mẫu Builder
Các lớp tham gia vào pattern này là:
• Builder: chỉ định một giao diện để tạo ra các bộ phận của đối tượng

Product.
• ConcreteBuilder: thực thi giao diện Builder. Nó định nghĩa và lưu vết

phần trình bày mà nó tạo ra và cung cấp cho interface để lưu lại Product.
• Director: chứa một tham chiếu Builder, khởi dựng đối tượng phức tạp

sử dụng giao diện Builder.
• Product: đại diện cho đối tượng phức tạp đang được xây dựng.

Client có thể là một đối tượng khác hoặc client thực tế mà gọi phương
thức main() của ứng dụng, khởi tạo lớp Builder và Director. Builder đại diện cho
các đối tượng phức tạp mà cần phải được xây dựng trong các điều khoản của các

đối tượng và các kiểu đơn giãn hơn. Constructor trong lớp Director nhận một
đối tượng Builder như một tham số từ Client và chịu trách nhiệm gọi các
phương thức thích hợp của lớp Builder. Để cung cấp cho Client một giao diện
cho tất cả các Builder cụ thể, lớp Builder nên là một lớp abstract. Bằng cách này,
bạn có thể thêm các kiểu mới của các đối tượng phức tạp bằng cách chỉ định cấu
trúc và tái sử dụng logic cho quá trình xây dựng thực tế. Client chỉ cần biết về
các kiểu, Director cần phải biết các phương thức của Builder để gọi.
2.1.3.5:Lợi ích
NGUYỄN NGỌC ÁNH-AT8B

22


Builder làm giúp quản lý dễ dàng luồng tổng thể trong việc tạo ra các đối
tượng phức tạp.
2.2 Mẫu thiết kế cấu trúc:
2.2.1: Mẫu Adapter
2.2.1.1: Giới thiệu
Đô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.(Chỉ với đối tượng adapter) ta cần sử dụng một vài lớp con đã tồn
tại, nhưng để làm cho các giao diện của chúng tương thích với nhau bằng việc
phân lớp các giao diện đó là việc làm không thực tế, để làm được điều này ta
dùng một đối tượng adapter để biến đổi giao diện lớp cha của nó.
2.2.1.2 Các khái niệm

Adapter[7] 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.
Để hiểu về sơ đồ mô tả Adapter Pattern thì trước hết bạn phải hiểu về 3
khái niệm:

Client: Đây là lớp sẽ sử dụng đối tượng của bạn (đối tượng mà bạn
muốn chuyển đổi giao diện).

Adaptee: Đây là những lớp bạn muốn lớp Client sử dụng, nhưng hiện
thời giao diện của nó không phù hợp.

Adapter: Đây là lớp trung gian, thực hiện việc chuyển đổi giao diện
cho Adaptee và kết nối Adaptee với Client.
2.2.1.3 Phân loại Adapter Pattern
Trong hướng đối tượng có hai khái niệm quan trọng song hành cùng nhau,
đó là


Composition: cấu thành. Nghĩa là một lớp B nào đó sẽ trở thành một
thành phần của lớp A(một field trong lớp A). Tuy lớp A không kế thừa lại
giao diện của lớp B nhưng nó có được mọi khả năng mà lớp B có.

NGUYỄN NGỌC ÁNH-AT8B

23


Inheritance: kế thừa. Nghĩa là một lớp Derived sẽ kế thừa từ lớp Base và
thừa hưởng tất cả những gì lớp Base có. Nhờ kế thừa mà nó giúp tăng khả

năng sử dụng lại code, tăng khả năng bảo trì và nâng cấp chương trình. Và
do vậy kế thừa là khái niệm trọng tâm trong hướng đối tượng. Nhưng nó
có một nhược điểm, đôi khi nếu chúng ta quá lạm dụng nó, nó sẽ làm cho
chương trình của chúng ta phức tạp lên nhiều, điển hình là trong lập trình
game. Do vậy, đôi lúc trong lập trình game người ta thường có khuynh
hướng thích sử dụng composition hơn.
Và ứng với hai khái niệm này sẽ cho ta hai cách để chúng ta cài đặt lớp
adapter: Object Adapter và Class Adapter.


2.2.1.4a: Object Adapter Pattern
Đây là một phương pháp cài đặt Adapter Pattern dựa trên ý tưởng về
composition. Lớp Adapter của chúng ta sẽ chứa một instance của lớp
Adaptee bên trong nó. Và giao diện của nó sẽ tương ứng với giao diện mà chúng
ta cần. Nhưng các phương thức trong giao diện đó không được định nghĩa, mà
nó chỉ gọi lại các phương thức tương ứng của lớp Adaptee . Adapter lúc này chỉ
như một cầu nối trung gian giữa Client và Adaptee, mục đích để chuyển đổi tên
phương thức mà Client gọi trên đối tượng Adapter thành phương thức tương
ứng ở lớp Adaptee.
Hay ta có thể hiểu đơn giản, đối với Object Adapter Pattern, ta sẽ sử dụng
một đối tượng Adapter để mặc (wrap) cho đối tượng Adaptee một bộ áo mới
(giao diện mới). Nếu tưởng tượng Adaptee là một người, thì Adapter chỉnh là
bộ đồ, khi Adaptee mặc lên mình Adapter thì Adaptee (lúc này là người) sẽ có
một vẻ bề ngoài (giao diện) khác.

Hình 2.1: Mẫu Object Adapter biểu diễn bằng UML
2.2.1.4b: Class Adapter Pattern
Đây là một phương pháp cài đặt Adapter Pattern dựa trên ý tưởng về
inheritance. Lớp Adapter của chúng ta sẽ kế thừa lớp Adaptee và thực thi cả
giao diện mới (giao diện mà Client cần). Các phương thức trong giao diện mới


NGUYỄN NGỌC ÁNH-AT8B

24


sẽ được cài đặt bằng cách gọi lại các phương thức tương ứng của Adaptee mà nó
kế thừa được.
Class Adapter tương tự với trường hợp sử dụng thiết bị output trên PC của
chúng ta. Hãy tưởng tượng bạn có một PC và một màn hình, người dùng
là Client, màn hình hiển thị của PC là Adaptee (coi nó là một “giao diện” hiển
thị), và máy in là TargetInterface. Giả sử giờ bạn không cần hiển thị một văn bản
trên màn hình nữa, mà bạn muốn nó hiển thị ra giấy. Do đó, bạn cần đến giao
diện của máy in (TargetInterface). Vì vậy, bạn sẽ cắm máy in vào máy tính của
bạn, và giờ đây nó vừa có thể hiển thị lên màn hình, vừa có thể hiển thị ra giấy,
lúc này hình ảnh của PC được cắm thêm máy in vào tương tự như một Class
Adapter. Bộ PC này (PC + màn hình + máy in) sẽ có cả giao diện hiển thị của
màn hình và giao diện hiển thị của máy tin. Tương tự, trong Class Adapter
Pattern, Adapter sẽ kế thừa cả giao diện của Adaptee và Target Interface.

Hình 2.2: Mẫu Class Adapter biểu diễn bằng UML.
2.2.1.5: Mẫu liên quan
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ý.

NGUYỄN NGỌC ÁNH-AT8B

25


×