Tài liệu: Một số patten khác

Tài liệu
Khoa CNTT ĐHSP KT Hưng Yên

Tóm tắt nội dung

-
Một số patten khác

Nội dung

Một số patten khác

Chúng ta quy ước với nhau rằng “giao diện lớp” được hiểu như interface hoặc abstract class vì đây đơn thuần là các định nghĩa lớp.

Factory pattern

Định nghĩa

Factory Pattern định nghĩa một lớp (interface, abstract, class) đóng vai trò như một “nhà xưởng” có nhiệm vụ khởi tạo đối tượng “cụ thể” khi ứng dụng chạy. Tại thời điểm thiết kế đối tượng này được định nghĩa trừu tượng.

- Ý nghĩa

Định nghĩa một phương thức chuẩn để khởi tạo đối tượng, như là một phần của phương thức tạo, nhưng việc quyết định kiểu đối tượng nào được tạo ra thì phụ thuộc vào các lớp con. - Cấu trúc mẫu

Trong đó:

+ Creator là lớp trừu tượng, khai báo phương thức factoryMethod() nhưng không cài đặt.

+ Product cũng là lớp trừu tượng.

+ ConcreteCreatorA và ConcreteCreatorB là 2 lớp kế thừa từ lớp Creator để tạo ra các đối tượng riêng biệt.

+ ConcreteProductA và ConcreteProductB là các lớp kế thừa của lớp Product, các đối tượng của 2 lớp này sẽ do 2 lớp ConcreteCreatorA và ConcreteCreatorB tạo ra.- Tình huống áp dụng

+ Khi bạn muốn tạo ra một framework có thể mở rộng, có nghĩa là nó cho phép tính mềm dẻo trong một số quyết định như chỉ ra loại đối tượng nào được tạo ra.

+ Khi bạn muốn 1 lớp con, mở rộng từ 1 lớp cha, quyết định lại đối tượng được khởi tạo.

+ Khi bạn biết khi nào thì khởi tạo một đối tượng nhưng không biết loại đối tượng nào được khởi tạo.

+ Bạn cần một vài khai báo chồng phương thức tạo với danh sách các tham số như nhau, điều mà Java không cho phép. Thay vì điều đó ta sử dụng các Factory Method với các tên khác nhau.- Ví dụ 6.3

Ta xét lại ví dụ về các địa chỉ ở phần Abstract Pattern

Phân loại

Factory Pattern được thiết kế theo một trong hai cách sau đây:

- Based-class Factory Pattern: Mẫu này sử dụng tính chất thừa kế để phân loại các đối tượng được tạo ra.

- Based-object Factory Pattern: Sử dụng mối quan hệ kết hợp để tham chiếu tới một đối tượng sẽ được tạo ra. Đối tượng được tạo ra sẽ trở thành một phần hay thuộc tính của lớp Factory. Chúng ta thường hay gặp loại này trong Abstract Factory Pattern được trình bày ở phần tiếp theo.

Abstract factory pattern

Định nghĩa

Abstract Factory cung cấp một giao diện lớp có chức năng tạo ra một tập hợp các đối tượng liên quan hoặc phụ thuộc lẫn nhau mà không chỉ ra đó là những lớp cụ thể nào tại thời điểm thiết kế.

Về bản chất, Abstract Factory Pattern chỉ khác Factory Pattern ở ch& #7895; bản thân đối tượng Factory không được chỉ ra cụ thể tại thời điểm thiết kế, tức nó là một giao diện hoặc lớp trừu tượng (interface, abstract). Nếu như Factory Patttern phân loại đối tượng dựa trên tham số đầu vào thì đối với Abstract Factory Pattern, thủ tục createObject() còn phụ thuộc thêm vào các yếu tố phụ khác như môi trường hệ điều hành chẳng hạn. Ứng với mỗi yếu tố phụ thứ hai ta có một lớp Factory cụ thể.

Thiết kế động với Abstract Factory

Một trong những vấn đề gặp phải là khung giao diện Abstract Factory thường hay bị sửa đổi, thí dụ như bổ sung thủ tục chẳng hạn, khi đó các lớp cụ thể thực thi giao diện này sẽ phải được dịch và triển khai lại. Để giảm nhẹ vấn đề này người ta thường thiết kế giao diện Abstract Factory một cách linh động.

Singleton pattern (Static Factory Pattern)

Định nghĩa

Singleton Pattern đảm bảo một lớp chỉ có một thực thể (instance) duy nhất được tạo ra và đồng thời cung cấp một truy cập toàn cục đến đối tượng được tạo ra.

Chúng ta xét trường hợp có nhiều đối tượng có cùng chung một số tính chất nào đó được tạo ra ứng với mỗi một yêu cầu từ các đối tượng khách (client), lúc này độ phức tạp sẽ tăng lên và ứng dụng sẽ chiếm dụng nhiều vùng nhớ hơn. Singleton Pattern là một giải pháp đặc biệt của Factory Pattern ở chỗ đối tượng sinh ra là điểm truy cập toàn cục “duy nhất” đối với mọi chương trình gọi đến, hay nói một cách khác tất cả các đối tượng khách gọi đến đều chia sẻ đối tượng được tạo ra.

Ứng dụng rõ rệt nhất của Singleton Pattern có thể thấy trong dịch vụ web khi triệu gọi các đối tượng từ xa, ở đó đối tượng nằm trên server hoặc sẽ phục vụ chung cho tất cả các ứng dụng khách (singleton) hoặc sẽ chỉ đáp ứng một ứng dụng khách riêng lẻ nào đó rồi tự bị phá huỷ sau đó (single call).

Về các mẫu thiết kế tiêu biểu trong nhóm cấu thành: Factory, Abstract Factory và Singleton, các bạn có thể tham khảo thêm tài liệu về phương pháp xây dựng cụ thể cũng như mã nguồn chương trình viết bằng C#.NET tại địa chỉ:

http://www.codeproject.com/gen/desig...assFactory.aspProxy pattern

Định nghĩa

Proxy Pattern là mẫu thiết kế mà ở đó tất cả các truy cập trực tiếp một đối tượng nào đó sẽ được chuyển hướng vào một đối tượng trung gian (Proxy Class).

Nếu như Factory Pattern giúp quản lý đối tượng tốt hơn thì Proxy Pattern lại có nhiệm vụ bảo vệ việc truy cập một đối tượng thông qua Proxy, hay còn gọi là truy cập gián tiếp. Proxy được ủy quyền về phía ứng dụng khách cho phép tương tác với đối tượng đích theo những cách khác nhau; như gửi yêu cầu một dịch vụ nào đó, theo dõi trạng thái và vòng đời đối tượng, xây dựng lớp vỏ bảo vệ đối tượng... Thí dụ chúng ta phát hiện ra một đối tượng trong một thư viện DLL có thể bị khai thác truy cập vào một số trường quan trọng, khi đó chúng ta không thể mở mã nguồn thư viện đã được dịch để vá lỗ hổng, giải pháp lúc này là xây dựng một proxy ngăn chặn truy cập các trường đó và cuối cùng biên dịch lại thành một DLL mới.

Phân loại

Độ phức tạp của giải pháp sử dụng Proxy Pattern phụ thuộc vào tình huống bài toán đưa ra, chúng ta sẽ lần lượt tìm hiểu nguyên tắc làm việc của các proxy dưới đây:

- Remote Proxy: Client truy cập qua remote proxy để tham chiếu tới một đối tượng được bảo vệ nằm bên ngoài ứng dụng (trên cùng máy hoặc máy khác) như dịch vụ Windows, dịch vụ web, ứng dụng ở xa... Mô hình này "che giấu" đối tượng được triệu gọi đang nằm ở rất xa đâu đó và client có vẻ như truy cập vào đối tượng nằm trên cù ng một chuyên khu làm việc (domain).

- Virtual Proxy: Virtual Proxy tạo ra một đối tượng trung gian mỗi khi có yêu cầu tại thời điểm thực thi ứng dụng, nhờ đó làm tăng hiệu suất của ứng dụng.

- Monitor Proxy: Monitor Proxy sẽ thiết lập các ràng buộc bảo mật trên đối tượng cần bảo vệ, ngăn không cho client truy cập một số trường quan trọng của đối tượng.

- Protection Proxy: Đối với proxy này thì phạm vi truy cập của các client khác nhau sẽ khác nhau. Protection Proxy sẽ kiểm tra các quyền truy cập của client khi có một dịch vụ được yêu cầu.

- Cache Proxy: Cung cấp không gian lưu trữ tạm thời cho các kết quả trả về từ đối tượng nào đó, kết quả này sẽ được tái sử dụng cho các client chia sẻ chung một yêu cầu gửi đến và do đó làm tăng đáng kể hiệu suất chương trình.

- Firewall Proxy: Bảo vệ đối tượng từ chối các yêu cầu xuất xứ từ các client không tín nhiệm.

- Smart Reference Proxy: Là nơi kiểm soát các hoạt động bổ sung mỗi khi đối tượng được tham chiếu, ví dụ như kiểm soát vòng đời của đối tượng, lưu lại số lần tham chiếu vào đối tượng...

- Synchronization Proxy: Đảm bảo nhiều client có thể truy cập vào cùng một đối tượng mà không gây ra xung đột. Thực tế có rất nhiều tình huống khiến chúng ta phải nghĩ đến thiết kế này. Một synchronization proxy được thiết lập có thể kiểm soát được nhiều yêu cầu cập nhật dữ liệu một cách đồng thời, tại thời điểm bắt đầu cập nhật chỉ có một client với mức ưu tiên cao nhất giành được khoá để đánh dấu rằng các client khác cần phải chờ đến lượt.

Synchronization proxy hoạt động rất hiệu quả và phổ biến trong thiết kế các bài toán đa tuyến. Một hiện tượng hay xảy ra với thiết kế này là khi một client nào đó chiếm dụng khoá khá lâu (và thậm chí là mãi mãi) khiến cho số lượng các client trong danh sách hàng đợi cứ tăng lên, và do đó hoạt động của hệ thống bị ngừng trệ, có thể dẫn đến hiện tượng “tắt nghẽn” là hiện tượng khoá được giữ vô thời hạn bởi một đối tượng nào đó. Trong trường hợp này người ta cải tiến thành mẫu thiết kế phức tạp hơn, đó là Copy-On-Write Proxy.

- Copy-On-Write Proxy: Cope-On-Write Proxy đảm bảo rằng sẽ không có client nào phải chờ vô thời hạn. Thiết kế này rất phức tạp do đó chỉ nên ứng dụng Copy-On-Write Proxy thay thế Synchronization Proxy khi hệ thống được dự đoán sẽ thường xuyên bị ngừng trệ hoặc có hiện tượng “tắt nghẽn” xảy ra.

Đặc điểm chung

Proxy Pattern có những đặc điểm chung sau đây:

Cung cấp mức truy cập gián tiếp vào một đối tượng.

Tham chiếu vào đối tượng đích và chuyển tiếp các yêu cầu đến đối tượng đó.

Cả proxy và đối tượng đích đều kế thừa hoặc thực thi chung một lớp giao diện. Mã máy dịch cho lớp giao diện thường “nhẹ” hơn các lớp cụ thể và do đó có thể giảm được thời gian tải dữ liệu giữa server và client.

Adapter pattern

Định nghĩa

Adapter Pattern biến đổi giao diện của một lớp thành một giao diện khác mà các đối tượng client có thể hiểu được. Lớp với giao diện được tạo ra đó gọi là Adapter. Nguyên tắc cơ bản của Adapter Pattern nằm ở chỗ làm thế nào để các lớp với các giao diện không tương thích có thể làm việc được với nhau.

Nguyên lý xây dựng Adapter Pattern khá đơn giản: chúng ta xây dựng một lớp với một giao diện mong muốn sao cho lớp đó giao tiếp được với một lớp cho trước ứ ng với một giao diện khác.

Adapter Pattern không quản lý tập trung các đối tượng gần giống nhau như Factory Pattern, mà kết nối với nhiều lớp không có liên quan gì với nhau. Ví dụ lớp A sau khi thực thi giao diện của nó và vẫn muốn bổ sung các phương thức từ một lớp B nào đó, chúng ta có thể kết nối A với B thông qua hình thức kế thừa hoặc liên kết đối tượng như một thành phần. Adapter Pattern có sự giống nhau một chút với Proxy Pattern ở chỗ nó tận dụng tối đa tính chất “uỷ quyền” (delegation); lớp Adapter sẽ kết nối với một đối tượng nào đó gọi là Adaptee và Adapter sẽ được uỷ quyền truy cập vào Adaptee, lớp Adapter đóng vai trò như một kênh trung gian để client truy cập vào một số các thành phần quan trọng của lớp Adaptee.

Đặc điểm

Adapter Pattern hướng tập trung vào giải quyết sự tương thích giữa hai giao diện đang tồn tại, giảm công sức viết lại mã lệnh xuống mức tối thiểu có thể được.

Tái sử dụng giao diện cũ và Adapter Pattern chỉ thực sự cần thiết khi mọi thứ đã được thiết kế từ trước.

Phạm vi ứng dụng

Adapter Pattern được ứng dụng trong các trường hợp:

Cần tích hợp một vài module vào chương trình.

Không thể sát nhập trực tiếp module vào chương trình (ví dụ như module thư viện đã được dịch ra .DLL, .CLASS...).

Module đang tồn tại không có giao diện mong muốn như:

  • Cần nhiều hơn phương thức cho module đó.
  • Một số phương thức có thể được nạp chồng.

Wrapper pattern

Wrapper Pattern là một trường hợp đặc biệt của Adapter Pattern. Nếu một Adapter chỉ đơn thuần là “nhúng” (wrap) các lớp với các giao diện không tương thíc h với nhau để chúng có thể hoạt động cùng nhau thì có thể được gọi bằng tên riêng Wrapper Pattern. Khi đó lớp Adapter còn được gọi là lớp Wrapper. Đây là quan hệ “có một”, tức là một giao diện không tương thích có thể được nhúng vào thành một phần của một giao diện khác.

Đặc điểm

Đối tượng Wrapper mô phỏng tất cả các hành vi (hàm, thủ tục) của giao diện được nhúng bởi các hành vi với tên y hệt. Thí dụ nếu lớp được nhúng A có thủ tục SpecificRequest() thì lớp Wrapper cũng phải có thủ tục SpecificRequest() tham chiếu đến thủ tục cùng tên của A. (Ngoài ra đối tượng Wraper có thể được bổ sung các phương thức khác nếu cần thiết). Đặc điểm này được đưa ra dựa trên nguyên tắc thiết kế “Law of Demeter” nói rằng không nên tham chiếu một đối tượng sâu hơn một lớp.

Các phương thức trong Adaptee được “nhúng” trong Wrapper bằng cách truyền lời gọi cùng với các tham số tới phương thức tương ứng trong Adaptee, và trả về kết quả giống như vậy. Các thành viên (thuộc tính, trường, sự kiện) được nhúng trong Wrapper có tính chất giống hệt như trong các lớp được nhúng (tên, kiểu dữ liệu, phạm vi truy cập...).

Từ các đặc điểm ở trên, có thể thấy rằng Wrapper Pattern cho phép một module chương trình tương tác được trong một môi trường khác biệt với môi trường phát triển của module đó (ví dụ C++ và Java).

Khác biệt giữa Wrapper Pattern và Adapter Pattern

Sự khác biệt giữa Wrapper và Adapter nằm ở mục đích sử dụng: Adapter Pattern định hướng cho một đối tượng đang tồn tại có thể làm việc được với các đối tượng khác và biến đổi logic theo một cách thức nào đó, trong khi Wrapper Pattern chỉ đơn thuần cung cấp một giao diện kết hợp các đối tượng được xây dựng từ cùng một ngôn ngữ hoặc khác ngôn ngữ, trên cùng một hệ điều hành hoặc trên những hệ điều hành khác nhau.

Proxy Adapter Pattern

Nếu một lớp Adapter đóng thêm vai trò như một proxy bảo vệ cho Adaptee thì ta có mô hình Proxy Adapter Pattern, trong trường hợp này chúng ta có thể đặt tên lớp với nghĩa kết hợp, ví dụ BankProxyAdapter.

Bài này đưa ra một số mẫu thiết kế tiêu biểu giúp các bạn thấy được tầm quan trọng của design pattern trong việc nâng cao chất lượng phần mềm ở các yếu tố: hiệu suất ứng dụng, độ ổn định, tái sử dụng, tính bảo mật... Các bạn có thể tìm hiểu thêm về các mẫu thiết kế cao cấp khác ở rất nhiều tài liệu thiết kế phần mềm.

Prototype- Ý nghĩa

Giúp khởi tạo đối tượng bằng cách copy một đối tượng khác đã tồn tại (đối tượng này là “prototype” – nguyên mẫu).- Cấu trúc mẫu

Trong đó:

+ Prototype là lớp trừu tượng cài đặt phương thức myClone() là phương thức copy bản thân đối tượng đã tồn tại.

+ ConcretePrototype1 và ConcretePrototype2 là các lớp kế thừa lớp Prototype.- Tình huống áp dụng

+ Khi bạn muốn khởi tạo một đối tượng bằng cách sao chép từ một đối tượng đã tồn tại.

- Ví dụ 6.4




Nguồn: voer.edu.vn/m/mot-so-patten-khac/aaa8a768


Chưa có phản hồi
Bạn vui lòng Đăng nhập để bình luận