Đối với mỗi mẫu, chúng ta sẽ xem xét vai trò của nó, một minh hoạ nơi nó có thể được sử dụng trong lập trình, và thiết kế của nó những gì chúngchính là và những gì là vai trò của chúng t
Trang 1CHƯƠNG II: CÁC MẪU CẤU TRÚC: DECORATOR, PROXY, VÀ BRIDGE
Chúng ta bắt đầu tour du lịch của chúng ta về các mẫu thiết kế với mộtnhóm được gọi là các mẫu cấu trúc Có bảy mẫu tạo nên nhóm cấu trúc, mỗimẫu với vai trò của việc xây dựng linh hoạt, tăng tuổi thọ, và bảo mật vàophần mềm máy tính Tên của các mô hình là quan trọng, vì vậy tôi sẽ giớithiệu chúng ngay sau đây Đó là:
Thêm chức năng mới tự động cho các đối tượng hiện có, hoặc loại bỏ
nó (Decorator)
Kiểm soát truy cập đến một đối tượng (proxy)
Tạo các đối tượng tốn kém theo yêu cầu (Proxy)
Cho phép sự phát triển giao diện và thực thi một thành phần một cáchđộc lập (Bridge)
Kết hợp các giao diện không tương thích (Adapter)
Giảm chi phí làm việc với số lượng lớn của các đối tượng rất nhỏ(Flyweight)
Tổ chức lại hệ thống với nhiều hệ thống con vào một định danh duynhất (Façade)
Chọn hoặc chuyển đổi việc triển khai khi chạy (Bridge)
Đơn giản hóa giao diện cho một hệ thống con phức tạp (mặt tiền)
Đối xử với đối tượng duy nhất và các đối tượng hỗn hợp trong cùngmột cách (Composite)
Các mẫu cấu trúc có thể được sử dụng trong khi một hệ thống đangđược thiết kế, hoặc sau này trong quá trình duy trì và mở rộng Trong thực tế,một số trong số chúng là đặc biệt hữu ích trong các giai đoạn hậu sản xuất của
Trang 2vòng đời một hệ thống phần mềm, khi thay đổi được đưa ra mà chưa đượclường trước và khi ngay cả các giao diện giữa các thành phần cần cập nhật Vìvậy, đôi khi bạn muốn thêm chức năng, bạn sẽ được làm việc với các lớp họchiện có mà không thể thay đổi Mẫu Decorator là hữu ích ở đây Ngoài ra, bạn
có thể thiết kế một hệ thống toàn bộ từ đầu để nó hoạt động theo một cách đặcbiệt sử dụng được, với mẫu Composite
Khám phá của chúng ta về các mẫu thiết kế cấu trúc sẽ kéo dài bachương Trong chương này, chúng ta sẽ xem xét các mẫu Decorator, Proxy,
và Bridge Trong chương 3, chúng ta sẽ giải quyết các mẫu Composite vàFlyweight, và trong chương 4, chúng ta sẽ kiểm tra các mẫu Adapter vàFaçade
Ba mẫu đầu tiên của chúng ta cung cấp cách thêm trạng thái và hành vi
tự động, kiểm soát việc tạo ra và truy cập các đối tượng, và giữ thông số kỹthuật và triển khai riêng biệt Chúng không sử dụng bất kỳ tính năng tiên tiếnnào của C#, chỉ dựa vào giao diện cho cấu trúc, tuy nhiên, ở phần cuối củachương này, chúng tôi giới thiệu phương pháp mở rộng như là một cách thú
vị để thực thi mẫu Bridge
Đối với mỗi mẫu, chúng ta sẽ xem xét vai trò của nó, một minh hoạ nơi
nó có thể được sử dụng trong lập trình, và thiết kế của nó (những gì chúngchính là và những gì là vai trò của chúng trong mô hình) Sau đó chúng tôi sẽxem xét một số mã đơn giản minh họa việc thực hiện các mẫu và một ví dụ cụthể hơn Cuối cùng, chúng tôi sẽ xem xét một số bổ sung thực tế sử dụng chocác mẫu và một số bài tập mà bạn có thể làm việc qua để nâng cao sự hiểubiết của bạn về nó Ngoài ra, vào cuối chương này và mỗi chương, bạn sẽ tìmthấy một cuộc thảo luận chi tiết hơn về khi nào các mẫu riêng lẻ có thể được
sử dụng và so sánh về ý tưởng và khả năng ứng dụng của chúng
Mẫu Decorator (trang trí)
Vai trò
Vai trò của mẫu Decorator là cung cấp một cách để đưa trạng thái vàhành vi mới cho một đối tượng tự động Các đối tượng không biết nó đangđược "trang trí", mà làm theo một mẫu hữu ích cho phát triển hệ thống Mộtđiểm quan trọng trong thực thi mẫu Decorator là sử dụng cả kế thừa các lớpban đầu và chứa một thể hiện của nó
Minh hoạ
Như tên gọi của nó cho thấy, mẫu Decorator có một đối tượng có sẵn
và các đối tượng thêm vào Ví dụ, hãy xem xét một bức ảnh được hiển thị trênmột màn hình Có rất nhiều cách để thêm vào bức ảnh, chẳng hạn như đặt mộtbiên giới xung quanh nó hoặc chỉ định các thẻ liên quan đến nội dung Những
bổ sung này có thể được hiển thị trên đỉnh của bức ảnh, như thể hiện tronghình 2-1
Trang 3Hình 2-1 Hình minh họa mẫu Decorator (a) ảnh đơn giản và (b) ảnh với các thẻ
Sự kết hợp của hình ảnh ban đầu và một số nội dung mới tạo thành mộtđối tượng mới Trong hình ảnh thứ hai thể hiện trong hình 2-1, có bốn đốitượng: hình ảnh ban đầu như thể hiện bên trái, đối tượng cung cấp một đườngviền, và hai đối tượng tag với dữ liệu khác nhau liên quan tới chúng Mỗi thứ
là một đối tượng Decorator Cho rằng số cách trang trí hình ảnh là vô tận,chúng ta có thể có nhiều đối tượng mới như vậy
Vẻ đẹp của mẫu này là:
Các đối tượng ban đầu là không biết về bất kỳ đồ vật trang trí nào
Không có một class đầy tính năng lớn với tất cả các tùy chọn trong đó
Các đồ trang trí độc lập với nhau
Các đồ trang trí có thể được sáng tác cùng nhau trong một thời trangtrộn lẫn và kết hợp
Thiết kế
Bây giờ, chúng ta có thể xác định những thứ trong mẫu Decoratortrong một sơ đồ UML, thể hiện trong hình 2-2 Bởi vì đây là mẫu đầu tiênchúng tôi mô tả trong UML, chúng ta sẽ đưa nó ra từ từ (UML mà chúng tacần cho mẫu trong cuốn sách này được đề cập trong Chương 1 và tóm tắttrong bảng 1-1.) Những thứ cần thiết trong sơ đồ UML này là:
Trang 4Giao diện mà xác định các lớp của các đối tượng có thể được trang trí(Component là một trong những lớp này)
Decorator
Một lớp có tuân theo giao diện IComponent và bổ sung thêm trạngthái và/hoặc hành vi (có thể có nhiều lớp như vậy)
Hình 2-2 biểu đồ lớp UML của mẫu Decorator
Trung tâm của sơ đồ UML là lớp Decorator Nó bao gồm hai loạiquan hệ với giao diện IComponent:
Is-a
Quan hệ is-a thể hiện bởi một mũi tên chấm chấm từ Decorator đếnIComponent, chỉ ra rằng Decorator thưc thi giao diệnIComponent Thực tế là Decorator thừa kế từ IComponent cónghĩa là đối tượng Decorator có thể được sử dụng bất cứ nơi nàocác đối tượng IComponent được mong đợi Lớp Component cũng
là một mối quan hệ is-a với IComponent, và do đó máy khách có thể
sử dụng các đối tượng Component và Decorator thay thế chonhau-trung tâm của mẫu Decorator
Has-a
Quan hệ has-a thể hiện bởi hình thoi mở trên Decorator, liên kết vớiIComponent Điều này cho thấy rằng các Decorator khởi tạo mộthoặc nhiều đối tượng IComponent và các đối tượng được trang trí cóthể sống lâu hơn bản gốc Decorator sử dụng các thuộc tính thànhphần (loại IComponent) để gọi bất kỳ hoạt động thay thế có thể đượcghi đè lên Đây là cách mẫu Decorator đạt được mục tiêu của mình.Thao tác addedBehavior và thuộc tính addedState trong lớpDecorator là những cách tùy chọn khác của việc mở rộng những gì cótrong các đối tượng Component ban đầu Chúng ta sẽ xem xét một số ví dụtrong giây lát
Trang 5Câu hỏi
Khớp các yếu tố mẫu Decorator với các minh họa trang trí hình ảnh
Để kiểm tra xem bạn hiểu mẫu Decorator, che cột trái của bảng dưới đây vàxem liệu bạn có thể xác định các đối tượng trong các mục từ ví dụ minh họa(Hình 2-1), như thể hiện trong cột bên tay phải Sau đó kiểm tra câu trả lời củabạn đối với các cột bên tay trái
IComponentComponentOperationDecoratorClientIComponent
Bức ảnh bất kìMột bức ảnh đơn giảnHiển thị một bức ảnhMột bức ảnh được gắn thẻTạo ra hình ảnh và gắn thẻ ảnhBức ảnh bất kì
Từ danh sách này, chúng ta có thể thấy rằng những điều sau đây sẽ làcâu lệnh hợp lệ trong một Client muốn đặt hai thẻ vào một hình ảnh:
Photo photo = new Photo( );
Tag foodTag = new Tag (photo, "Food",1);
Tag colorTag = new Tag (foodTag, "Yellow",2);
Do quan hệ is-a, photo, foodTag, và colorTag tất cả là đối tượngIComponent Mỗi thẻ (các trang trí) được tạo ra với một Component, mà
có thể là một hình ảnh hoặc một bức ảnh đã được gắn thẻ Dẫn đến sơ đồ đốitượng được thể hiện trong hình 2-3 Như bạn thấy, thực sự có ba đối tượnghình ảnh riêng biệt trong hệ thống Cách chúng tương tác được thảo luậntrong phần "Triển khai" sắp tới
Hình 2-3 Các đối tượng trong mẫu Decorator
Trong hầu hết các mẫu, chúng ta sẽ gặp, các đối tượng có thể xuất hiệntrong nhiều vỏ bọc Để giữ cho các sơ đồ UML rõ ràng và đơn giản, khôngphải tất cả các tùy chọn sẽ được hiển thị Tuy nhiên, chúng ta nên xem xétnhững tác động của những đối tượng trên thiết kế của các mẫu:
Đa thành phần
Các thành phần khác nhau tuân theo giao diện cũng có thể được trangtrí Ví dụ, chúng ta có thể có một lớp mà thu hút mọi người, nhà cửa,tàu, và như vậy từ các hình dạng đơn giản và đường Chúng cũng có
Trang 6thể được gắn thẻ Đây là lý do mà giao diện IComponent là quantrọng, ngay cả khi nó không chứa bất kỳ thao tác nào Trong trườnghợp chúng tôi chắc chắn có sẽ chỉ là một lớp các thành phần, chúng tôi
sẽ bỏ qua giao diện IComponent và có các trang trí kế thừa trực tiếpComponent
Các trang trí
Chúng ta thấy rằng chúng ta có thể tạo ra các trường hợp khác nhau củamột thẻ trang trí Chúng tôi cũng có thể xem xét việc có các loại trangtrí, chẳng hạn như các trang trí biên hoặc thậm chí có các trang trí màlàm cho hình ảnh ẩn đi Không có vấn đề gì về trang trí, mỗi thứ cóchứa một thành phần đối tượng, mà có thể chính là một trang trí, thiếtlập ra một chuỗi các thay đổi (như đề xuất trong Hình 2-3) Một số thiết
kế mẫu Decorator bao gồm một giao diện IDecorator, nhưng nóthường không có mục đích hiện thực trong C#
Đa thao tác
Minh họa của chúng ta tập trung vào việc vẽ như các hoạt động chínhcho các ảnh và đồ trang trí Ví dụ khác sẽ vay mượn để nhiều thao táctùy chọn hơn Một số trong số này sẽ là một phần của thành phần banđầu và giao diện của nó, trong khi một số sẽ được thêm vào hành vitrong duy nhất một trang trí nhất định Client có thể gọi bất kỳ hoạtđộng riêng lẻ trên bất kỳ thành phần (trang trí hay cách khác) mà nó cóquyền truy cập
Thực hiện
Tính năng quan trọng của mẫu Decorator là nó không dựa trên thừa kế
để mở rộng hành vi Nếu lớp Tag phải kế thừa từ lớp hình ảnh để thêm mộthoặc hai phương thức, Tag sẽ mang tất cả mọi thứ liên quan đến hình ảnh ,làm cho chúng thành đối tượng rất nặng Thay vào đó, có lớp Tag thực hiệnmột giao diện hình ảnh và sau đó thêm hành vi giữ đối tượng Tag tinh gọn.Chúng có thể:
Thực hiện phương thức bất kỳ trong giao diện, thay đổi hành vi ban đầucủa các thành phần
Thêm bất cứ trạng thái và hành vi mới nào
Truy cập bất kỳ thành viên công cộng qua các đối tượng thông quaphương thức khởi tạo
Trước khi chúng tôi thực hiện với những hình ảnh ví dụ, hãy xem xétcác phiên bản lý thuyết của mẫu Decorator sau đó trong Ví dụ 2-1 Ví dụ ngắnnhư thế này rất hữu ích cho thấy sự tương tác giữa các lớp và các đối tượngcủa một mô hình trong một bản đồ trực tiếp đến UML Một khi chúng tachuyển sang một ví dụ thực tế, tối ưu hóa và phần mở rộng có thể được sửdụng làm cho nó khó khăn hơn để phát hiện và định hình mẫu sẽ sử dụng
Trang 7Hơn nữa, trong một ví dụ thực tế, tên của các yếu tố có thể hoàn toàn khác sovới mô tả mẫu.
Ví dụ 2-1 Đoạn code lý thuyết mẫu Decorator
6. // Decorator Pattern Judith Bishop Dec 2006
7. // Shows two decorators and the output of various
8. // combinations of the decorators on the basic component
Trang 875. IComponent component = new Component();
76. Display("1 Basic component: ", component);
77. Display("2 A-decorated : ", new DecoratorA(component));
78. Display("3 B-decorated : ", new DecoratorB(component));
79. Display("4 B-A-decorated : ", new DecoratorB(
80. new DecoratorA(component)));
81. // Explicit DecoratorB
82. DecoratorB b = new DecoratorB(new Component());
83. Display("5 A-B-decorated : ", new DecoratorA(b));
84. // Invoking its added state and added behavior
91 Basic component: I am walking
92 A-decorated : I am walking and listening to Classic FM
93 B-decorated : I am walking to school
94 B-A-decorated : I am walking and listening to Classic FM to school
95 A-B-decorated : I am walking to school and listening to Classic
FM past the Coffee Shop and I bought a cappuccino
96 */
Ví dụ bắt đầu với giao diện IComponent và một lớp Componentđơn giản mà thực thi nó (dòng 9-21) Có hai trang trí cũng thực thi giao diện,mỗi thứ trong số chúng bao gồm một khai báo của IComponent, đó là đốitượng mà nó sẽ trang trí DecoratorA (dòng 23-39) là khá đơn giản và chỉcần thực hiện các hoạt động bằng cách gọi nó trên các thành phần nó đã đượclưu trữ, sau đó thêm một cái gì đó để chuỗi của nó trả về (dòng 35).DecoratorB (dòng 40-61) là phức tạp hơn Nó cũng thực thi Operationtheo cách riêng của nó, nhưng nó cung cấp addedState (dòng 43) vàphương thức addedBehavior (dòng 57-61) public Trong hoạt động thựcthi, phương thức Operation của thành phần được gọi đầu tiên, nhưng điềunày không phải là một yêu cầu của mẫu, nó chỉ đơn thuần là làm cho đầu ra
dễ đọc hơn trong ví dụ này
Trang 9Lớp Client có trách nhiệm tạo các thành phần và trang trí trong cáccấu hình khác nhau và hiển thị kết quả của phương thức Operation trongmỗi trường hợp Trường hợp 2 và 3 (dòng 77-78) trang trí các thành phần cơbản trong những cách khác nhau, như ở đầu ra trên dòng 92-93 Trường hợp 4
và 5 áp dụng hai trang trí, B và A, trong hai thứ tự khác nhau Trong trườnghợp 2-4, các đối tượng trang trí được thể hiện và được sử dụng ngay lập tức,sau đó bỏ đi Trong trường hợp 5, chúng tôi tạo ra một đối tượngDecoratorB và giữ trường hợp này trong một biến cùng loại (thay vìIComponent), vì vậy chúng tôi có thể gọi hành vi mới:
DecoratorB b = new DecoratorB(new Component( ));
Display("5 A-B-decorated : ", new DecoratorA(b));
// Invoking its added state and added behavior
cơ bản "I am walking" đã được trả lại (dòng 19) Tiếp tục như trên,DecoratorB thêm chút thông tin về đi bộ đến trường (dòng 53), và sau đóDecoratorA cho biết thêm "nghe Classic FM" (dòng 35) Điều này hoànthành các cuộc gọi đến hiển thị Như có thể được nhìn thấy trên dòng 95, kếtquả là trái ngược với dòng 94 bởi vì trang trí được soạn theo một thứ tự khác
Tuy nhiên, đó không phải là tất cả Trang trí có thể xác định hành vimới, có thể được gọi một cách rõ ràng Chúng tôi làm điều này trên dòng 85,
mà kết quả trong dòng thứ hai của đầu ra (dòng95) về việc mua một ly cà phêcappuccino
Điều đó, tóm lại, là cách trang trí làm việc Trang trí không cần bất kỳtính năng ngôn ngữ cao cấp, chúng dựa vào đối tượng tổng hợp và thực thigiao diện Bây giờ, chúng ta hãy xem xét một ví dụ thực tế
Ví dụ: Hình ảnh trang trí
Trong phần này, chúng tôi sẽ xem xét làm thế nào để thực hiện một hệthống trang trí hình ảnh, như mô tả trong phần "Minh họa", trước đó Nhấnmạnh rằng thành phần ban đầu đã được viết trước đây và không khả dụng choviệc thay đổi, chúng tôi sẽ đặt nó trong một không gian tên riêng biệt gọi làGiven:
using System.Windows.Forms;
namespace Given {
// The original Photo class
public class Photo : Form {
Image image;
public Photo ( ) {
Trang 10image = new Bitmap("jug.jpg");
static void Main ( ) {
// Application.Run acts as a simple client
Application.Run(new Photo( ));
}
Bây giờ, mà không thay đổi bất cứ điều gì trong lớp Photo, chúng ta
có thể bắt đầu thêm các trang trí Đầu tiên vẽ một đường viền màu xanh xungquanh bức ảnh (chúng ta sẽ giả định kích thước đã biết để giữ cho mọi thứđơn giản):
// This simple border decorator adds a colored border of fixed size
class BorderedPhoto : Photo {
Tag trang trí theo một hình thức tương tự, vì vậy chúng ta có thể đưavào thành phần sau đây:
// Compose a photo with two tags and a blue border
foodTag = new Tag (photo, "Food", 1);
colorTag = new Tag (foodTag, "Yellow", 2);
Trang 11composition = new BorderedPhoto(colorTag, Color.Blue);
Application.Run(composition);
Kết quả của khối này về trang trí được thể hiện trong hình 2-1 (b) Chú
ý rằng trang trí có thể được khởi tạo với các thông số khác nhau để cung cấpcho các hiệu ứng khác nhau: đối tượng foodTag có một tham số thứ hai là
"Food", và tham số thứ hai của colorTag là "Yellow"
Cuối cùng, hãy kiểm tra trạng thái thêm vào và hành vi đó trong cácTag Một lớp Tag khai báo một mảng tĩnh và đếm chứa các tên thẻ nhưchúng đưa ra Bất kỳ đối tượng tag trang trí sau đó có thể gọi phương thứcListTags để hiển thị tất cả các thẻ hiện trong kịch bản Chương trình đầy
đủ được đưa ra trong ví dụ 2-2
Ví dụ 2-2 Ví dụ mẫu Decorator — Photo Decorator
7 // Decorator Pattern Example Judith Bishop Aug 2007
8 // Draws a single photograph in a window of fixed size
9 // Has decorators that are BorderedPhotos and TaggedPhotos
10 // that can be composed and added in different combinations
11 namespace Given
13 // The original Photo class
14 public class Photo : Form
Trang 1248 // a specific place to be written
49 class TaggedPhoto : Photo
51 Photo photo;
52 string tag;
53 int number;
54 static int count;
55 List<string> tags = new List<string>();
56 public TaggedPhoto(Photo p, string t)
73 string s = "Tags are: ";
74 foreach (string t in tags) s += t + " ";
87 foodTaggedPhoto = new TaggedPhoto(photo, "Food");
88 colorTaggedPhoto = new TaggedPhoto(foodTaggedPhoto,
93 photo = new Photo();
94 tag = new TaggedPhoto(photo, "Jug");
95 composition = new BorderedPhoto(tag, Color.Yellow);
96 Application.Run(composition);
97 Console.WriteLine(tag.ListTaggedPhotos());
Trang 1398 }
100 /* Output
101 TaggedPhotos are: Food Yellow
102 TaggedPhotos are: Food Yellow Jug
Một điểm quan trọng về mô hình Decorator là nó được dựa trên các đốitượng mới được tạo ra với bộ thao tác riêng của chúng Một số có thể được ditruyền, nhưng chỉ xuống một mức Ví dụ, khi thực hiện chương trình PhotoDecorator, chúng ta có thể cố gắng để thay đổi thuộc tính của lớp WindowsForm, như Height và Width, từ bên trong một đối tượng trang trí Đối vớithành phần chính nó và cho một trang trí mức đầu tiên, điều này sẽ làm việc.Nhưng ngay sau khi có một mức thứ hai của trang trí, những thay đổi sẽkhông được thông qua Lý do là hiển nhiên từ sơ đồ đối tượng trong hình 2-3:trình trang trí đầu tiên giữ một tham chiếu đến các đối tượng Windows Formthực tế, nhưng các trang trí cấp hai thì không Cho các loại hình thao tác một
mô hình khác, chẳng hạn như Strategy (được thảo luận trong Chương 7), sẽ làphù hợp hơn
Trong ví dụ của chương trình Photo Decorator, chúng ta đã không thực
sự thêm bất kỳ hành vi nào, chúng ta chỉ ghi đè nó Một Client thực hiệnđúng như khai báo Application.Run sử dụng mô hình sự kiện để gọiPaintEventHandler ngầm Nó không cung cấp một cơ hội để gọi cácphương thức khác một cách rõ ràng Tất nhiên, các sự kiện khác (chẳng hạnnhư MouseMove và OnClick) có thể được lập trình, và sau đó là các hành
vi khác trong trang trí sẽ có ý nghĩa (xem "Bài tập" sau này)
Sử dụng
Dưới đây là bốn cách mẫu Decorator được sử dụng trong thế giới thực:
Như là ví dụ nhỏ của chúng tôi minh họa, mẫu Decorator rất phù hợptrong thế giới đồ họa Cũng bằng nhau với video và âm thanh, ví dụ,video có thể được nén ở mức khác nhau, và âm thanh có thể được nhậpvào với một dịch vụ phiên dịch
Ở mức thông dụng hơn, trang trí có rất nhiều trong các API I/O của C#.Xem xét các hệ thống phân cấp sau đây:
System.IO.Stream System.IO.BufferedStream System.IO.FileStream System.IO.MemoryStream System.Net.Sockets.NetworkStream System.Security.Cryptography.CryptoStream
Các lớp con trang trí Stream vì chúng kế thừa từ nó, và chúng cũngchứa một thể hiện của một Stream được thiết lập khi một đối tượngđược xây dựng Nhiều thuộc tính và phương thức của chúng liên quanđến trường hợp này
Trang 14 Trong thế giới ngày nay của các thiết bị di động, trình duyệt web và cácứng dụng di động khác phát triển mạnh trên các mẫu Decorator Chúng
có thể tạo ra màn hình hiển thị các đối tượng phù hợp với màn hình nhỏhơn bao gồm thanh cuộn và loại trừ banner, đó sẽ là tiêu chuẩn trên cáctrình duyệt hiển thị trên máy tính để bàn, như ví dụ
Mẫu Decorator rất hữu ích, hiện nay có lớp Decorator trong NET 3.0.Một trong số đó ở System.Windows.Controls "cung cấp mộtlớp cơ sở cho các yếu tố áp dụng hiệu ứng lên hoặc xung quanh mộtphần tử con duy nhất, chẳng hạn như Border hoặc ViewBox."
Bảng sau đây tóm tắt khi nào, nói chung, nên sử dụng mẫu Decorator
Sử dụng mẫu Decorator khi
Bạn có thể
Xác định rằng có những hoạt động mà không phải luôn luôn cần đượcthực hiện theo cùng một cách
Bạn muốn
Hoàn toàn ẩn việc triển khai từ phía client
Tránh gắn một thực thi trực tiếp với một trừu tượng
Thay đổi một thực thi mà không biên dịch lại trừu tượng
Kết hợp các bộ phận khác nhau của một hệ thống ở thời gian chạy
Bài tập
1 Giả sử rằng lớp Photo đã được viết với Drawer như một phươngthức gốc (không ảo) và nó không thể được thay đổi Xây dựng lại ví dụ2-2 để nó hoạt động trong hạn chế này (Gợi ý: Sử dụng một giao diệnnhư trong ví dụ lý thuyết.)
2 Thêm vào hệ thống Photo Decorator kiểu thứ hai của thành phần gọi là
Hominid Sử dụng các phương pháp vẽ cho hình bầu dục và đường để
vẽ kết quả gần đúng của một người Sau đó, sử dụng hai trang trí tương
tự Tag và Border để trang trí các đối tượng Hominid.
3 Thêm xử lý sự kiện khác cho constructor của trang trí, cùng với hành vi
bổ sung Ví dụ, một sự kiện OnClick có thể làm một thẻ xuất hiện, thay
vì nó tự động xuất hiện
4 Trang trí lớp Console để phương thức Write và WriteLine bịbẫy và đầu ra là định dạng lại cho dòng xuất với một kích thước nào đó,tránh bọc quanh khó coi Kiểm tra trang trí của bạn với chương trìnhtrong ví dụ 2-1
Trang 155 Viết một chương trình trang trí lớp Stream và cho thấy bao nhiêu củamột tập tin đã được đọc trong đó, sử dụng một trackbar.
6 Viết một chương trình trang trí lớp Stream và yêu cầu một mật khẩutrước khi cho phép tiếp tục đọc
7 Viết một chương trình trang trí một tin nhắn văn bản với một thuật toán
mã đơn giản Bao gồm trang trí thứ hai có thể biến đổi các tin nhắnđược mã hóa trở lại văn bản gốc
Mẫu Proxy
Vai trò
Mẫu Proxy hỗ trợ các đối tượng kiểm soát việc tạo ra và truy cập vàođối tượng khác Proxy thường là một đối tượng nhỏ (public) mà ở trong đómột đối tượng phức tạp hơn (private) kích hoạt khi trường hợp nhất định rất
rõ ràng
Minh hoạ
Một hiện tượng lớn trong thế giới ngày nay là sự gia tăng phổ biến của
hệ thống mạng cộng đồng, nổi bật nhất trong số đó là Facebook Một phiêngiao dịch từ Facebook được thể hiện trong hình 2-4
Hình 2-4 Minh hoạ mẫu Proxy— một trang trong hệ thống mạng xã hội
Một tính năng của các hệ thống này là nhiều người đăng ký làm nhưvậy chỉ để xem những gì người khác đang làm và không tích cực tham giahoặc thêm nội dung Do đó nó có thể là một chính sách tốt nếu bắt đầu mỗingười mới tham gia bằng một trang đơn giản và không cấp cho người sử dụng
Trang 16bất kỳ không gian lưu trữ thực tế hoặc truy cập vào bất kỳ phương tiện nàocho đến khi họ bắt đầu thêm bạn bè và thông điệp.
Một tính năng của các hệ thống này là bạn phải lần đầu tiên đăng kývới hệ thống và sau đó đăng nhập vào tại mỗi phiên Sau khi đăng nhập, bạn
có thể truy cập vào các trang web của bạn bè Tất cả các hành động mà bạn cóthể thực hiện (chọc, viết trên các bức tường, gửi quà tặng, vv) có nguồn gốc ởtrình duyệt và được gửi qua mạng tới máy chủ Facebook gần nhất Các đốitượng là các trang Facebook, các proxy là cơ chế cho phép đăng ký và đăngnhập
Thiết kế
Thiết kế của một proxy và các yếu tố của nó được thể hiện trong sơ đồUML trong hình 2-5
Hình 2-5 Sơ đồ UML mẫu Proxy
Các yếu tố trong mẫu là:
mà các hành động thực sự diễn ra Proxy thực hiện công việc ở lối vào Giátrị của nó có thể được tăng cường bằng cách làm cho Subject thành một
Trang 17lớp riêng để các khách hàng không thể đến được với các Subject ngoại trừthông qua Proxy.
Câu hỏi
Khớp các yếu tố mẫu Proxy với minh họa Facebook
Để kiểm tra xem bạn hiểu mẫu Proxy, che cột trái của bảng dưới đây và xemliệu bạn có thể xác định các đối tượng trong các mục từ ví dụ minh họa (Hình2-1), như thể hiện trong cột bên tay phải Sau đó kiểm tra câu trả lời của bạnđối với các cột bên tay trái
ISubject
SubjectSubject.Request
ProxyProxy.Request
Client
Một danh sách các hành động có thể được thựchiện trên các trang
Trang thực tế thuộc về một ngườiThay đổi thực sự các trang
Lối vào các trang thực tếThực hiện một số hành động trước khi định tuyếncác yêu cầu
Một người sử dụng truy cập các trang của mình
Có một số loại proxy, phổ biến nhất trong số đó là:
Proxy ảo(Virtual proxies)
Điều khiển việc tạo ra của một đối tượng qua một đối tượng khác (hữuích nếu quá trình tạo có thể bị chậm hoặc có thể chứng minh là khôngcần thiết)
Proxy chứng thực(Authentication proxies)
Kiểm tra các quyền truy cập cho một yêu cầu có chính xác hay không
Proxy từ xa(Remote proxies)
Mã hoá yêu cầu và gửi chúng qua mạng
Proxy thông minh(Smart proxies)
Thêm vào hoặc thay đổi yêu cầu trước khi gửi chúng
Trong phạm vi của hệ thống mạng xã hội đề cập trước đó, các bản đồnhư sau:
Trì hoãn việc tạo ra một môi trường phong phú (proxy ảo)
Đăng nhập vào người sử dụng (proxy xác thực)
Gửi yêu cầu qua mạng (proxy từ xa)
Thực hiện các hành động trên trang của bạn bè (proxy thông minh)
Thực hiện
Trang 18Một mục tiêu chính của cuốn sách này là để giới thiệu tính năng thú vịcủa C# và cho thấy làm thế nào để sử dụng chúng viết mẫu dễ dàng hơn, rõràng hơn, và an toàn hơn Vì mỗi tính năng mới tìm thấy một nơi trong một
mô hình, tôi sẽ giới thiệu nó qua một thanh bên Ví dụ này minh họa việc sửdụng một số từ khóa sửa đổi truy cập của C# là trọng tâm của thanh bên đầutiên của chúng tôi
Từ khóa sửa đổi
truy cập
private Truy cập trong phương thức
hoặc nơi mà nó được khai báo
Các thành viên của lớp
và cấu trúc; các kiểu lồngnhau
internal Truy cập trong assembly Kiểu không lồng nhau
protected Truy cập bên trong một class và
Làm thế nào sự chia rẽ giữa Client một bên và các proxy hoặc Subject
ở bên khác có thể được triển khai với từ khóa sửa đổi truy cập khắt khenhất có thể
Làm thế nào câc virtual và protection proxy thực hiện công việc vàđịnh tuyến yêu cầu của chúng về sau
Mã cơ bản của virtual proxy là thế này:
public class Proxy : ISubject
Trang 19phương thức Request được gọi mà tham chiếu Subject được kiểm tra và,nếu là null, gán cho một đối tượng cụ thể.
Mã đầy đủ cho ví dụ lý thuyết được trình bày trong ví dụ 2-3 Ví dụnhấn mạnh rằng tất cả các trường trong ứng dụng được khai báo như kiểugiao diện, ISubject Điều này có nghĩa là truy cập vào các hoạt động bổsung trong proxy, như Authenticate, sẽ yêu cầu các đối tượngISubject được ép kiểu phù hợp, như xảy ra trên dòng 63 và 64 Các ví dụbao hàm proxy thứ hai trong lớp ProtectionProxy (dòng 31-50) Proxynày là độc lập với những thứ khác Nếu một đối tượng ProtectionProxyđược khai báo, như trên dòng 61, tất cả các yêu cầu đầu tiên sẽ phải đáp ứngmột chỉ dẫn để xác thực Trong ví dụ này, Authenticate là một phươngthức riêng biệt mà phải được gọi, như trong dòng 63 và 64 Trong ví dụ tiếptheo, việc đăng ký và xác thực sẽ tự động khởi động khi Request được gọi
Tính năng C#— sửa đổi truy cập
Ở mức vật lý, một chương trình C# bao gồm một hoặc nhiều đơn vị biên dịch,mỗi đơn vị chứa trong một tập tin mã nguồn riêng biệt Khi một chương trìnhC# được biên dịch, tất cả các đơn vị biên dịch được xử lý với nhau Vì vậy,đơn vị biên dịch có thể phụ thuộc vào nhau, có thể theo một vòng tròn Một
assembly là một thứ chứa vật lý với các kiểu và các nguồn tài nguyên liên
quan đến chúng
Ở mức logic, các chương trình C# được tổ chức sử dụng các không gian tên
(namespace) Namespace được sử dụng như một cách để trình bày các yếu tố
chương trình được tiếp xúc với các chương trình khác trong cùng và khácassembly Sửa đổi truy cập là một cách để chỉ rõ các thành viên của một tênmiền không gian sẽ được tiếp xúc ở mức độ nào
Trong C#, một sửa đổi truy cập thay đổi khả năng tiếp cận mặc định của mộtkiểu hay các thành viên của nó Các bổ từ có sẵn và giá trị mặc định nhận ápdụng được trình bày ở Bảng 2-1 Trong bảng này, các loại bao gồm các lớp,cấu trúc, giao diện, enums, và delegate Việc giải thích bảng này cho các lớpnhư sau:
Một lớp không lồng nhau theo mặc định là có thể nhìn thấy các lớpkhác trong cùng một assembly
Một lớp lồng theo mặc định là private và có thể không có khả năng tiếpcận nhiều hơn lớp chứa nó
Một thành viên của một lớp (ví dụ trường, phương thức, thuộc tính)theo mặc định là private
Một lớp kế thừa có thể có quyền truy cập đặc biệt cho một thành viêntrong lớp cha của nó đã được gắn với truy cập protected
Trừ khi bạn đang làm phát triển assembly chéo, các từ khoá public là không
Trang 20thực sự cần thiết; Tuy nhiên, nó có một loại tiền tệ trong lập trình mà các từkhoá internal thì không Do đó nó chấp nhận dùng public khi gắn thẻ thànhviên để truy cập bên ngoài lớp Nhu cầu thực sự cho truy cập internal chặt chẽhơn được minh họa trong phần "Ví dụ".
Có một số hạn chế như từ khoá kiểm soát truy cập có thể được đặt ở đâu vànhư thế nào Các thành viên của một giao diện luôn là public, và không thayđổi nào được phép Namespace không thể có thành viên private hoặcprotected từ khoá chỉ có thể được thêm vào các loại và các thành viên để làmcho chúng dễ tiếp cận các phương thức hoặc các lớp kèm theo của chúng.Theo C# Language Specification phiên bản 3.0, Tháng chín 2007, mục 10.3.5
Ví dụ 2-3 Đoạn code lý thuyết mẫu Proxy
1. using System;
2. // Proxy Pattern Judith Bishop Dec 2006
3. // Shows virtual and protection proxies
36. string password = "Abracadabra";
37. public string Authenticate(string supplied)