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.. Nhóm
Trang 1BAN 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 tinChuyên ngành: An toàn thông tin
Mã số: 52.48.02.01
Hà Nội, 2016
Trang 2BAN 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 tinChuyên ngành: An toàn thông tin
Trang 3LỜ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.
Trang 4MỤC LỤC
Trang 5DANH MỤC HÌNH ẢNH
Trang 6DANH MỤC BẢNG
Trang 7DANH MỤC TỪ VIẾT TẮT
OLTP Online Tenure and Promotion System
Trang 8LỜ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
Trang 9Chươ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ế
Trang 10CHƯƠ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
Trang 11pattern 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
Trang 12cá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
Trang 13CHƯƠ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ế
Tần suất sử dụng: cao
2 Builder 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.Tần suất sử dụng: trung bình thấp
3 Factory
Method
Định nghĩa Interface để sinh ra đối tượng nhưng để cho 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á
Trang 14trình khởi tạo đối tượng cho lớp con.
Tần suất sử dụng: cao
4 Prototype 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
Tần suất sử dụng: trung bình
5 Singleton Đả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ó
Tần suất sử dụng: cao trung bình
Mẫu thiết kế cấu trúc (Structural Pattern)
6 Adapter 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
Tần suất sử dụng: cao trung bình
7 Bridge 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
Tần suất sử dụng: trung bình
8 Composite 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ì
Tần suất sử dụng: cao trung bình
9 Decorator 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)
Tần suất sử dụng: trung bình
10 Facade 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
Trang 15cho hệ thống con dễ sử dụng hơn.
Tần suất sử dụng: cao
11 Flyweight 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ự…)
Tần suất sử dụng: thấp
12 Proxy 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
Tần suất sử dụng: cao trung bình
Mẫu thiết kế hành vi (Behavioral Pattern)
13 Chain of
Responsibility
Khắc phục việc ghép cặp giữa bộ gửi và bộ nhận thông đ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ể.Tần suất sử dụng: trung bình thấp
14 Command 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…
Tần suất sử dụng: cao trung bình
15 Interpreter 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ữ
Tần suất sử dụng: thấp
16 Iterator Truy xuất các phần tử của đối tượng dạng tập hợp tuần
Trang 16tự (list, array, …) mà không phụ thuộc vào biểu diễn bên trong của các phần tử Tần suất sử dụng: cao
17 Mediator Đị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
Tần suất sử dụng: trung bình thấp
18 Memento 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.Tần suất sử dụng: thấp
19 Observer Đị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
Tần suất sử dụng: cao
20 State 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
Tần suất sử dụng: trung bình
21 Strategy 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
Tần suất sử dụng: cao trung bình
22 Visitor 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 đó
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
Trang 172.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 đó:
Trang 18Singleton: 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.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
Trang 19Để 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
Trang 20• 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ó
Để 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
Trang 21Mộ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
Trang 22Hì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
Trang 23Builder 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ó
Trang 24 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
Trang 25sẽ đượ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ý
Trang 26Proxy đị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ó
2.2.2: Mẫu Proxy
2.2.2.1: Giới thiệu
Lý do để điều khiển truy nhập tới một đối tượng là làm theo toàn bộ quá trình tạo ra và khởi đầu của nó cho tới tận khi thực sự chúng ta cần sử dụng nó.Trong trường hợp này ta nên dùng mẫu thiết kế proxy Proxy có thể được ứng dụng tại bất cứ nơi nào mà ở đó cần có một sự tham chiếu tới một đối tượng linh hoạt hơn, tinh xảo hơn so với việc sử dụng một con trỏ đơn giản Sau đây là một vài trường hợp thông thường trong đó proxy được vận dụng:
Một remote proxy cung cấp một biểu diễn (một mẫu) cục bộ cho một đối tượng trong một không gian địa chỉ khác
Một virtual proxy tạo ra một đối tượng có chi phí cao theo yêu cầu - Một protection proxy điều khiển việc truy nhập đối tượng gốc Các protection proxy rất hữu ích khi các đối tượng có các quyền truy nhập khác nhau
Một smart reference là sự thay thế cho một con trỏ rỗng cho phép thực hiện các chức năng thêm vào khi một đối tượng được truy nhập.Các trường hợp
sử dụng điển hình:
• Đếm số tham chiếu tới đối tượng thực, do đó nó có thể tự động giải phóng khi
có không nhiều các tham chiếu
• Tải một đối tượng liên tục vào bộ nhớ khi nó được tham chiếu lần đầu tiên
• Kiểm tra đối tượng thực đó có được khóa hay không trước khi nó bị truy nhập
để đảm bảo không đối tượng nào khác có thể thay đổi nó
2.2.2.2: Định nghĩa
Cung cấp một đại diện cho một đối tượng khác để điều khiển việc truy nhập nó
2.2.2.3: Lược đồ UML