Sơ đồ lớp mẫu Proxy

Một phần của tài liệu (LUẬN VĂN THẠC SĨ) Phát triển mẫu thiết kế phần mềm và ứng dụng (Trang 31)

 Proxy (MathProxy)

 Duy trì một tham chiếu để cho proxy truy cập vào một đối tƣợng thực. Proxy có thể tham khả đến một chủ thể nếu nhƣ giao diện của RealSubject và Subject là nhƣ nhau.

 Cung cấp một giao diện xác định Subject để một proxy có thể thay thế cho đối tƣợng thực.

 Điều khiển truy cập tới đối tƣợng thực và có thể chịu trách nhiệm tạo ra và xoá nó đi.

 Trong các nhiệm vụ khác phụ thuộc vào từng loại proxy: Remote proxies chịu trách nhiệm cho việc mã hoá một yêu cầu và các tham số của nó và để truyền yêu cầu mã hoá cho chủ thể trong không gian địa chỉ khác; Virtual proxies có thể thêm phần thông tin đệm về chủ thể thực để chúng có thể trì hoãn truy nhập nó; Protection proxies kiểm tra đối tƣợng gọi đã có yêu cầu quyền truy nhập để thực hiện một yêu cầu.

 Subject (IMath): định nghĩa một giao diện chung cho chủ thể thực và Proxy để proxy có thể sử dụng ở mọi nơi mà một RealSubject mong đợi.

 RealSubject (Math): định nghĩa đối tƣợng thực mà proxy đại diện.

Một Adapter cung cấp một giao diện khác với đối tƣợng mà nó thích nghi. Trong trƣờng hợp này, một Proxy cung cấp cùng một giao diện nhƣ vậy giống nhƣ một chủ thể.

Mặc dù decorator có thể có cài đặt tƣơng tự nhƣ các proxy, decorator có một mục đích khác. Một decorator phụ thêm nhiều nhiệm vụ cho một đối tƣợng nhƣng ngƣợc lại một proxy điều khiển truy cập đến một đối tƣợng.

Proxy tuỳ biến theo nhiều cấp khác nhau mà chúng có thể sẽ đƣợc cài đặt giống nhƣ một decorator. Một proxy bảo vệ có thể đƣợc cài đặt chính xác nhƣ một decorator. Mặt khác một proxy truy cập đối tƣợng từ xa sẽ không chứa một tham chiếu trực tiếp đến chủ thể thực sự nhƣng chỉ duy nhất có một tham chiếu trực tiếp, giống nhƣ ID của host và địa chỉ trên host vậy. Một proxy ảo sẽ bắt đầu với một tham chiếu gián tiếp chẳng hạn nhƣ tên file nhƣng rốt cuộc rồi cũng sẽ đạt đƣợc một tham chiếu trực tiếp.

1.3.3. Nhóm mẫu hành vi

Nhóm gồm có 11 mẫu: Interpreter, Template Method, Chain of Responsibility, Command, Iterator, Mediator, Memento, Observer, State, Strategy và Visitor. Nhóm này liên quan đến việc 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. Xem thông tin về các mẫu thuộc nhóm này 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 giải thích cách chuyển giao các chức năng.

1.3.3.1. Chain of Responsibility

Xét bài toán xây dựng hệ thống trợ giúp phụ thuộc ngữ cảnh cho một giao diện đồ hoạ; trong đó ngƣời sử dụng có thể lấy thông tin trợ giúp về bất cứ thành phần nào của giao diện bằng cách ấn vào nó. Thông tin trợ giúp cung cấp phụ thuộc vào thành phần giao diện đựơc chọn và ngữ cảnh của nó. Lấy ví dụ một nút trong một hộp thoại sẽ có thông tin trợ giúp khác với một nút tƣơng tự trong cửa sổ chính. Ngoài ra nếu không có thông tin trợ giúp nào đƣợc cung cấp cho thành phần đựơc chọn của giao diện, hệ thống trợ giúp sẽ hiển thị thông tin trợ giúp tổng quát hơn về ngữ cảnh, lấy ví dụ thông tin về hộp thoại.

Bài toán trên dẫn đến một hành động rất tự nhiên đó là tổ chức các thông tin trợ giúp theo mức độ tổng quát của chúng, từ cụ thể nhất đến tổng quát nhất. Ngoài ra chúng ta cũng dễ dàng nhận thấy rằng yêu cầu trợ giúp sẽ đƣợc xử lý bởi một trong số các đối tƣợng giao diện ngƣời dùng phụ thuộc vào ngữ cảnh sử dụng và tính chi tiết của thông tin trợ giúp đƣơc cung cấp.

Vấn đề đặt ra ở đây là đối tƣợng khởi xƣớng yêu cầu không hề biết yêu cầu đó sẽ đƣợc xử lý bởi đối tƣợng cụ thể nào. Vì thế chúng ta cần có cơ chế tách rời chúng, và mẫu Chain of Responsibility xây dựng mô hình để thực hiện điều này:

Hình 1.16. Sơ đồ tương tác

Theo mô hình này, đối tƣợng đầu tiên trong dây chuyền sẽ nhận đƣợc yêu cầu có thể xử lý yêu cầu đó hoặc chuyển nó cho đối tƣợng kế tiếp; điều tƣơng tự cũng xảy ra với đối tƣợng này. Bằng cách này, đối tƣợng khởi xƣớng yêu cầu không cần biết yêu cầu sẽ đƣợc xử lý bởi đối tƣợng nào, nó chỉ biết rằng yêu cầu đó sẽ đựơc xử lý một cách “hợp lý” nhất.

Giả sử ngƣời sử dụng yêu cầu trợ giúp cho một nút có tiêu đề “Print”. Nút đó đƣợc đặt trong hộp thoại PrintDialog. Đến lƣợt mình, hộp thoại đó lại có khả năng xác định lớp Application chứa nó. Sơ đồ tƣơng tác sau sẽ cho thấy cách thức yêu cầu trợ giúp đó đựơc truyền đi dọc theo dây chuyền:

Hình 1.17. Biểu đồ cộng tác

Trong trƣờng hợp này, cả hai đối tƣợng aPrintButton và aPrintDialog đều không xử lý yêu cầu trợ giúp; vì thế yêu cầu này đựơc chuyển tới cho aApplication để xử lý hoặc bỏ qua không làm gì.

Để có khả năng chuyền yêu cầu dọc theo dây chuyền và để đảm bảo tính “ẩn” của các đối tƣợng có thể nhận yêu cầu (với đối tƣợng khởi xƣớng yêu cầu), mỗi đối tƣợng trên dây chuyền đều có chung một giao diện trong việc xử lý yêu cầu và chuyển yêu cầu cho đối tƣợng kế tiếp. Lấy ví dụ, hệ thống trợ giúp có thể định nghĩa lớp HelpHandler với phƣơng thức HandleHelp tƣơng ứng. Lớp HelpHandler có thể đựơc lấy làm lớp cha của các lớp mà ta muốn cung cấp khả năng xử lý yêu cầu trợ giúp:

Hình 1.18. Mô hình lớp

Các lớp Button, Dialog và Application sử dụng các phƣơng thức HandleHelp để xử lý yêu cầu trợ giúp trong khi phƣơng thức này mặc định chỉ chuyển tiếp yêu cầu trợ giúp cho nút kế tiếp. Khi đó các lớp con có thể định nghĩa lại phƣơng thức này để cung cấp thông tin trợ giúp cụ thể hoặc chỉ sự dụng phƣơng thức mặc định để chuyển tiếp yêu cầu theo dây chuyền.

Định nghĩa: mẫu Chain of Responsiblity dùng để tránh sự liên kết trực tiếp giữa đối tƣợng gửi yêu cầu và đối tƣợng nhận yêu cầu khi yêu cầu có thể đựơc xử lý bởi hơn một đối tƣợng. Móc nối các đối tƣợng nhận yêu cầu thành một chuỗi và gửi yêu cầu theo chuỗi đó cho đến khi có một đối tƣợng xử lý nó.

Hình 1.19. Sơ đồ lớp mẫu Chain of Responsibility

 Handler (Approver)

 Nắm giữ các yêu cầu mà nó đáp ứng  Có thể truy nhập nó

 Nếu ConcreteHandle có thể nắm giữ các yêu cầu, nó sẽ làm nhƣ vậy, bằng không nó se gửi các yêu cầu tới các succcesor

 Client (ChainApp): khởi tạo yêu cầu tới đối tƣợng ConcreteHandler trên chuối đáp ứng.

Mẫu Chain of Responsibility có các khả năng và hạn chế sau :

 Giảm kết nối. Thay vì một đối tƣợng có khả năng xử lý yêu cầu chứa tham chiếu đến tất cả các đối tƣợng khác, nó chỉ cần một tham chiếu đến đối tựơng tiếp theo.

 Tăng tính linh hoạt và phân chia trách nhiệm cho các đối tƣợng. Có khả năng thay đổi dây chuyền trong thời gian chạy.

 Không đảm bảo có đối tƣợng xử lý yêu cầu.

Chúng ta sử dụng mẫu Chain of Responsibility trong các trƣờng hợp sau :

 Ccó lớn hơn một đối tƣợng có khả thực xử lý một yêu cầu trong khi đối tƣợng cụ thể nào xử lý yêu cầu đó lại phụ thuộc vào ngữ cảnh sử dụng.

 Muốn gửi yêu cầu đến một trong số vài đối tƣợng nhƣng không xác định đối tƣợng cụ thể nào sẽ xử lý yêu cầu đó.

 Tập các đối tƣợng có khả năng xử lý yêu cầu là một tập biến đổi.

Chain of Responsibility thƣờng đƣợc kết hợp trong mối quan hệ với composite.Có một thành phần cha có thể hành động nhƣ là successor của nó.

1.3.3.2. Command

Đôi khi chúng ta gặp tình huống trong đó cần phải gửi yêu cầu đến một đối tƣợng mà không biết cụ thể về đối tƣợng nhận yêu cầu cũng nhƣ phƣơng thức xử lý yêu cầu. Lấy ví dụ về bộ công cụ giao diện ngƣời sử dụng cho phép xây dựng các menu. Rõ ràng, nó không thể xử lý trực tiếp yêu cầu trên các đối tƣợng menu vì cách thức xử lý phụ thuộc vào từng ứng dụng cụ thể.

Mẫu Command cho phép bộ công cụ nhƣ trên gửi yêu cầu đến các đối tƣợng chƣa xác định bằng cách biến chính yêu cầu thành một đối tƣợng. Khái niệm quan trọng nhất của mẫu này là lớp trừu tƣợng Command có chức năng định nghĩa giao diện cho việc thi hành các yêu cầu. Trong trƣờng hợp đơn giản nhất, ta chỉ cần định nghĩa một thủ tục ảo Execute trên giao diện đó. Các lớp con cụ thể của Command sẽ xác định cặp đối tƣợng nhận yêu cầu-các thao tác bằng cách lƣu trữ một tham chiếu đến đối tƣợng nhận yêu cầu và định nghĩa lại thủ tục Execute để gọi các thủ tục xử lý.

Hình 1.20. Mô hình tương tác

Theo cách này, chƣơng trình sẽ có nhiệm vụ tạo ra các menu, menuitem và gán mỗi menuitem với một đối tƣợng thuộc lớp con cụ thể của Command. Khi ngƣời sử dụng chọn một menuitem, nó sẽ gọi hàm command->Execute() mà không cần con trỏ command trỏ đến loại lớp con cụ thể nào của lớp Command. Hàm Execute() sẽ có nhiệm vụ xử lý yêu cầu.

Định nghĩa: mẫu Command đóng gói yêu cầu nhƣ là một đối tƣợng, làm cho nó có thể đƣợc truyền nhƣ một tham số, đƣợc lƣu trữ trong một history list hoặc thao tác theo những cách thức khác nhau.

Hình 1.21. Sơ đồ lớp mẫu Command

 Cài đặt Execute bằng cách gọi một thao tác tƣơng ứng trên Receiver

 Client (CommandApp): tạo ra một đối tƣợng ConcreteCommand và thiết lập đối tƣợng nhận của nó

 Invoker (User): đề nghị command để thực hiệu yêu cầu

 Receiver (Calculator): biết cách để thực hiện các thao tác kết hợp việc thực hiện các yêu cầu

Dùng mẫu Command khi :

 Tham số hoá các đối tƣợng theo thủ tục mà chúng thi hành, nhƣ đối tƣợng MenuItem ở trên.

 Xác định, xếp hàng và thi hành các yêu cầu tại những thời điểm khác nhau.

 Cho phép quay ngƣợc. Thủ tục Execute của lớp Command có thể lƣu lại trạng thái để cho phép quay ngƣợc các biến đổi mà nó gây ra. Khi đó lớp Command trừu tƣợng cần định nghĩa thêm hàm Unexecute để đảo ngƣợc các biến đổi. Các commands đã đƣợc thi hành sẽ đƣợc lƣu trong một danh sách, từ đó cho phép undo và redo không giới hạn mức.

 Cần hỗ trợ ghi lại các commands đã đựơc thi hành để thi hành lại trong trƣờng hợp hệ thống gặp sự cố.

 Thiết kế một hệ thống với các thủ tục bậc cao đựơc xây dựng dựa trên các thủ tục nguyên thuỷ. Cấu trúc này thƣờng gặp trong các hệ thống thông tin hỗ trợ “phiên giao dịch”. Một phiên giao dịch là một tập hợp các sự thay đổi lên dữ liệu. Mẫu Command cung cấp cách thức mô tả phiên giao dịch. Nó có giao diện chung cho phép khởi xƣớng các phiên làm vịêc với cùng một cách thức và cũng cho phép dễ dàng mở rộng hệ thống với các phiên giao dịch mới.

Một Composite có thể đƣợc sử dụng để cài đặt các MacroCommands.

Một Memmento có thể lƣu lại các trạng thái để Command yêu cầu phục hồi lại các hiệu ứng của nó.

Một command phải đƣợc sao lƣu trƣớc khi nó đƣợc thay thế bằng các hành động trƣớc đó nhƣ là một Prototype.

1.3.3.3. Interperter

Nếu một dạng bài toán có tần suất xuất hiện tƣơng đối lớn, ngƣời ta thƣờng biểu diễn các thể hiện cụ thể của nó bằng các câu trong một ngôn ngữ đơn giản. Sau đó ta có thể xây dựng một trình biên dịch để giải quyết bài toán bằng cách biên dịch các câu.

Ví dụ, tìm kiếm các xâu thoả mãn một mẫu cho trƣớc là một bài toán thƣờng gặp và các “biểu diễn thông thƣờng” tạo thành ngôn ngữ dùng để diễn tả các mẫu của

xâu. Thay vì xây dựng từng thuật toán riêng biệt để tƣơng ứng mỗi mẫu với một tập các xâu, ngƣời ta xây dựng thuật toán tổng quát có thể phiên dịch các “biểu diễn thông thƣờng” thành tập các xâu tƣơng ứng.

Mẫu Interpreter miêu tả cách thức xây dựng cấu trúc ngữ pháp cho những ngôn ngữ đơn giản, cách thức biểu diễn câu trong ngôn ngữ và cách thúc phiên dịch các câu đó. Trong ví dụ cụ thể này, nó miêu tả cách thức xây dựng cấu trúc ngữ pháp cho các biểu diễn thông thƣờng, cách thức xây dựng biểu diễn thông thƣờng và cách thúc phiên dịch các biểu diễn thông thƣờng đó.

Giả sử cấy trúc ngữ pháp sau xác định các biểu diễn thông thƣờng:

expression ::= literal | alternation | sequence | repetition | '(' expression ')'

alternation ::= expression '|' expression sequence ::= expression '&' expression repetition ::= expression '*'

literal ::= 'a' | 'b' | 'c' | ... { 'a' | 'b' | 'c' | ... }* Mẫu Interpreter sử dụng các lớp để diễn tả các quy luật ngữ pháp. Khi đó cấu trúc ngữ pháp trên đƣợc diễn tả bởi năm lớp : lớp trừu tƣợng RegularExpression và bốn lớp con của nó : LiteralExpression, AlternationExpression, SequenceExpression và RepetitionExpression trong đó ba lớp cuối có các biến để chứa các biểu thức con.

Hình 1.22. Mô hình cấu trúc

Mỗi biểu diễn thông thƣờng xác định bởi cấu trúc ngữ pháp trên đều đựơc miêu tả bởi một cây cú pháp có thành phần là các đối tƣợng của các lớp trên. Lấy ví dụ biểu diễn raining & (dogs | cats) * đƣợc miêu tả bởi cây sau :

Hình 1.22. Mô hình cây phân cấp

Chúng ta có thể tạo ra trình biên dịch cho các biểu diễn trên bằng cách định nghĩa thủ tục Interpret trên từng lớp con của RegularExpression. Hàm này nhận tham số đầu vào là ngữ cảnh phiên dịch biểu diễn bao gồm xâu đầu vào và thông tin về lƣợng xâu đã đựơc ghép. Nó sẽ tiếp tục ghép phần tiếp theo của xâu dựa trên ngữ cảnh đó.

Ví dụ:

 LiteralExpression sẽ kiểm tra xem đầu vào có trùng với bảng chữ cái nó định nghĩa không.

 AlternationExpression sẽ kiểm tra xem thông tin đầu vào có phải là một trong các lựa chọn của nó không.

 ....

Định nghĩa: Interpreter đƣa ra một ngôn ngữ, xây dựng cách diễn đạt ngôn ngữ đó cùng với một trình phiên dịch sử dụng cách diễn tả trên để phiên dịch các câu.

Hình 1.23. Sơ đồ lớp mẫu Interperter

 AbstractExpression (Expression)

 Khai báo một giao diện cho việc thực hiện một thao tác TerminalExpression (ThousandExpression, HundredExpression, TenExpression, OneExpression )

 Cài đặt một thao tác thông dịch liên kết với những ký pháp đầu cuối  Một thể nghiệm đƣợc yêu cầu cho mọi ký pháp đầu cuối trong câu

NonterminalExpression ( not used )

 Một lớp nhƣ vậy đƣợc yêu cầu cho các luật R::=R1R2..Rn trong dãy cú pháp

 Duy trì một biến thể nghiệm của kiểu AbstractExpression cho mỗi một ký pháp R1 đến Rn

 Cài đặt một phƣơng thức thông dịch cho các ký pháp không phải đầu cuối.

 Thông dịch tự gọi đệ quy cho các biến đại diện từ R1 đến Rn

 Context (Context): chứa thông tin toàn cục cho việc thông dịch

phát từ thể nghiệm của các lớp NonterminalExpression và TerminalExpression

 Yêu cầu một thao tác thông dịch.

Sử dụng mẫu Interpreter khi cần phiên dịch một ngôn ngữ mà ta có thể miêu tả các câu bằng cầu trúc cây cú pháp. Mẫu này hoạt động hiệu quả nhất khi :

 Cấu trúc ngữ pháp đơn giản. Với các cấu trúc ngữ pháp phức tạp, cấu trúc lớp của ngữ pháp trở nên quá lớn và khó kiểm soát, việc tạo ra các cây cú pháp sẽ tốn thời gian và bộ nhớ.

 Hiệu quả không phải là yếu tố quan trọng nhất. Các cách thức biên dịch hiệu quả nhất thƣờng không áp dụng trực tiếp mẫu Interpreter mà phải biến đổi các biểu diễn thành các dạng khác trƣớc.

Cây cú pháp trừu tƣợng là một thể nghiệm trong mẫu Composite.

Flyweight chỉ ra cách chia sẻ ký pháp đầu cuối trong phạm vi của cây cú pháp

Một phần của tài liệu (LUẬN VĂN THẠC SĨ) Phát triển mẫu thiết kế phần mềm và ứng dụng (Trang 31)

Tải bản đầy đủ (PDF)

(113 trang)