SlideShare una empresa de Scribd logo
1 de 16
MẪU TRANG TRÍ
Mục đích
Gắn các chức năng bổ sung cho các đối tượng (gán động). Decorator cung
cấp một số thay đổi mềm dẻo cho các phân lớp để mở rộng thêm các chức năng.
Còn được biết đến là
Phương pháp "Đóng gói"
Động cơ
Đôi khi chúng ta muốn thêm các chức năng cho các đối tượng riêng lẻ , chứ không
phải cho toàn bộ một lớp. Ví dụ một bộ giao diện người dùng công cụ đồ họa, sẽ
cho phép bạn thêm các thuộc tính như Border (viền) hoặc các hành vi như di
chuyển đến bất kỳ giao diện người sử dụng thành phần nào.
Một cách để thêm chức năng là sử dụng Thừa kế. Kế thừa một Border từ
một lớp khác , đặt Border trong mỗi thực thể của lớp con. Cách này không linh
hoạt, tuy nhiên, vì ta chọn việc thiết lập các Border là tĩnh. Một người dùng không
thể kiểm soát việc tùy chỉnh các thành phần với Border khi nào và như thế nào.
Một cách tiếp cận linh hoạt hơn là đính kèm theo các thành phần trong một đối
tượng khác có thêm Border. Đối tượng này được gán thêm này gọi là Decorator.
Các Decoratror phù hợp với giao diện của các thành phần mà nó trang trí để thể
hiện của nó là (rõ ràng) minh bạch với người sử dụng. Các Decorator gửi yêu cầu
đến các thành phần để có thể thực hiện các hành động bổ sung (như vẽ một đường
viền) trước hoặc sau khi giao nhận. Việc Minh bạch hoá cho phép bạn tổ chức
trang trí đệ quy, do đó cho phép thêm một số lượng không giới hạn các chức năng.
Ví dụ, giả sử chúng ta có một đối tượng TextView hiển thị văn bản trong một cửa
sổ. TextView không có thanh cuộn theo mặc định, bởi vì chúng ta có thể ko phải
lúc nào cũng cần đến chúng. Khi chúng ta làm, chúng ta có thể sử dụng một Scroll
Decorator để thêm vào. Giả sử chúng ta cũng muốn thêm một đường viền màu đen
dày quanh TextView. chúng ta cũng có thể sử dụng một Decorator Border để
thêm vào. Chúng ta chỉ đơn giản là soạn các trang trí với TextView để tạo
các kết quả mong muốn.
Các sơ đồ đối tượng sau đây cho thấy làm thế nào để tạo ra một đối tượng
TextView với đối tượng Border Decorator và Scroll Decorator để tạo ra một
Border ( đường viền), và thanh cuộn xem văn bản:
Các lớp Scroll Decorator và Border Decorator là lớp con của Decorator, một
lớp trừu tượng cho các thành phần trực quan để trang trí các thành phần trực quan
khác.
VisualComponent (thành phần trực quan) là lớp trừu tượng cho các đối tượng trực
quan. Nó định nghĩa bản vẽ và xử lý sự kiện trong giao diện. Lưu ý các lớp
Decorator chỉ đơn giản chuyển tiếp yêu cầu vẽ cho các thành phần của nó, và làm
thế nào các lớp con của Decorator có thể mở rộng hoạt động này
Các Lớp con của Decorator được thêm các hoạt động cho các chức năng cụ thể
một cách thoải mái. Ví dụ, hoạt động ScrollTo của Decorator cho phép các đối
tượng khác di chuyển các giao diện nếu họ biết những thứ diễn ra là một đối tượng
ScrollDecorator trong giao diện. Các khía cạnh quan trọng của mô hình này là nó
cho phép Các mẫu trang trí (decorator) xuất hiện bất cứ nơi nào một thành phần
trực quan (VisualComponent) xuất hiện. Đó là cách người dùng thông thường
không thể biết sự khác biệt giữa một thành phần trang trí và một thành phần không
trang trí, và vì vậy chúng không phụ thuộc vào tất cả các trang trí phía trên.
Ứng dụng
Sử dụng Decorator khi:
 Thêm các chức năng bổ sung cho các đối tượng riêng biệt một cách động và
trong suốt, nghĩa là không chịu ảnh hưởng (tác động ) của các đối tượng
khác.
 Cho các chức năng mà các chức năng này có thể được rút lại (hủy bỏ) (nếu
không cần nữa).
 Khi sự mở rộng được thực hiện bởi các phân lớp là không thể thực hiện
được. Đôi khi một lượng lớn các mở rộng độc lập có thể thực hiện được
nhưng lại tạo ra một sự bùng nổ các phân lớp để trợ giúp cho các kết hợp.
Hoặc một định nghĩa lớp có thể bị che đi hay nói cách khác nó không có giá
trị cho việc phân lớp.
....
Cấu trúc
Các thành phần
 Component
o Định nghĩa giao diện cho đối tượng mà có thể có các chức năng thêm
vào nó vào một cách tự động
 ConcreteComponent
o Định nghĩa một đối tượng để có thể gắn thêm chức năng vào thành
phần cho nó
 Decorator
o Duy trì một tham chiếu tới một đối tượng thành phần và định nghĩa
một giao diện mà phù hợp với giao diện của thành phần.
 ConcreteDecorator
o Thêm nhiệm vụ cho thành phần
!
Sự tương tác
Decorator chuyển tiếp yêu cầu đến đối tượng thành phần của nó. Nó có thể tùy
chọn thực hiện các hoạt động bổ sung trước hoặc sau khi chuyển tiếp yêu cầu
!
Hệ quả
Các mô hình trang trí có ít nhất hai lợi ích quan trọng và 2 nhược điểm:
1. Linh hoạt hơn là thừa kế tĩnh. Các mẫu trang trí cung cấp một cách linh hoạt
hơn để thêm chức năng cho các đối tượng có thể có nhiều các thừa kế
tĩnh. Với trang trí, các chức năng có thể được thêm vào và lấy ra trong thời
gian chạy chỉ đơn giản bằng cách gắn và tách chúng.
Ngược lại, thừa kế đòi hỏi phải tạo ra một lớp mới cho mỗi lần thêm
tính năng (ví dụ, BorderedScrollableTextView, BorderedTextView). Điều
này dẫn đến có nhiều class và làm tăng sự phức tạp của một hệ thống.
Hơn nữa, cung cấp các lớp trang trí khác nhau cho một thành phần cụ thể
của lớp cho phép bạn pha trộn và làm phù hợp với chức năng
Trang trí cũng làm cho nó dễ dàng để thêm một thuộc tính hai lần. Ví dụ, để
cung cấp cho một TextView một viền đôi, chỉ cần đính kèm hai Border trang
trí. Kế thừa từ một lớp Border hai lần là lúc dễ bị lỗi nhất
2. Để tránh các Lớp bị đầy tính năng cao cấp trong các hệ thống phân
cấp. Decorator cung cấp một phương pháp tiếp cận pay-as-you-go(chi trả tùy
khả năng ) để thêm chức năng. Thay vì cố gắng để hỗ trợ tất cả các tính
năng có thể dự đoán trong một phức tạp, tùy lớp, bạn có thể định nghĩa một
lớp đơn giản và thêm chức năng từng bước với Decorator đối tượng. Chức
năng có thể được tạo ra từ những mảnh đơn giản. Kết quả là, một ứng dụng
không cần phải chi trả(pay) cho các tính năng nó không sử dụng. Nó cũng dễ
dàng để xác định các loại mới về trang trí độc lập với các lớp của các đối
tượng mở rộng, ngay cả đối với các phần mở rộng không lường trước
được. Mở rộng một lớp phức tạp có xu hướng để lộ các chi tiết liên quan đến
chức năng mà bạn đang thêm
3. Một trang trí và thành phần của nó không giống nhau. Một hành vi trang trí
như một vỏ bọc trong suốt. Nhưng từ một cái nhìn nhận dạng đối tượng,
một thành phần trang trí không đồng nhất với các thành phần của chính
nó. Do đó bạn không nên dựa vào nhận dạng đối tượng khi bạn sử dụng
trang trí.
4. Rất nhiều đối tượng nhỏ. Một thiết kế có sử dụng Decorator thường cho ra
kết quả là trong hệ thống có nhiều đối tượng nhỏ mà gần như tất cả giống
nhau. Các đối tượng khác nhau chỉ ở cách chúng liên kết với nhau, không ở
trong lớp hoặc trong các giá trị của các biến của chúng. Mặc dù các hệ thống
này dễ dàng tuỳ biến bởi những người hiểu biết, họ có thể gặp khó khăn để
tìm hiểu và gỡ lỗi
!
 Thực hiện
Một số vấn đề cần được xem xét khi áp dụng các mô hình trang trí - Decorator
pattern:
1. Giao diện phù hợp. Giao diện của một đối tượng trang trí phải phù hợp với
giao diện của các thành phần nó trang trí. Do đó các lớp ConcreteDecorator
phải kế thừa từ một lớp thông thường (ít nhất là trong C ++).
2. Bỏ qua các lớp Decorator trừu tượng. Không cần phải xác định một lớp
Decorator trừu tượng khi bạn chỉ cần thêm một chức năng. Đó là trường hợp
thường khi bạn đang làm việc với hệ thống lớp hiện thời hơn là thiết kế một
cái mới. Trong trường hợp đó, bạn có thể kết hợp chức năng của Decorator
để chuyển tiếp yêu cầu đến thành phần vào trong ConcreteDecorator.
3. Giữ các lớp Component gọn nhẹ. Để đảm bảo một giao diện phù hợp, các
thành phần và các trang trí phải giảm xuống từ một lớp thông thường. Điều
này là quan trọng là để giữ cho lớp này gọn nhẹ; nghĩa là, nó nên tập trung
vào việc xác định một giao diện, không lưu trữ dữ liệu. Định nghĩa của các
biểu diễn dữ liệu nên được hoãn lại đến lớp con; nếu không thì sự phức tạp
của các lớp có thể làm cho các trang trí quá nặng để sử dụng với số lượng
lớn. Đặt rất nhiều chức năng vào các thành phần cũng làm tăng xác suất mà
lớp con sẽ phải trả cho tính năng mà chúng không cần.
4. Thay đổi bề ngoài (Skin) của một đối tượng so với thay đổi cốt lõi(ruột) của
nó. Chúng ta có thể nghĩ về một trang trí như một lớp da ở một vật thể mà
thay đổi hành vi của nó. Một giải pháp thay thế là để thay đổi phần cốt lõi
(ruột) của đối tượng. Strategy (349) là một ví dụ của một mô hình để thay
đổi ruột.
Chiến lược(strategy) là một lựa chọn tốt hơn trong các tình huống mà các
lớp có bản chất nặng(phức tạp), do đó làm cho các mô hình trang trí quá tốn
kém để áp dụng. Trong các mô hình chiến lược, các thành phần chuyển tiếp
một số hành vi của mình cho một đối tượng chiến lược riêng biệt (độc
lập). Các mô hình chiến lược cho phép chúng ta thay đổi hay mở rộng chức
năng của các thành phần bằng cách thay thế các đối tượng Strategy(chiến
lược).
Ví dụ, chúng ta có thể hỗ trợ các kiểu Border khác nhau bởi có 1 thành phần
Vẽ Border độc lập với đối tượng Border. Các đối tượng Border là một đối
tượng Strategy mà bao hàm một Strategy ( chiến lược) Vẽ Border. Bằng
cách mở rộng số lượng các chiến lược từ một đến một danh sách mở, chúng
ta đạt được hiệu quả tương tự như trang trí đệ quy.
Ví dụ, Trong MacApp 3.0 [App89] và Bedrock [Sym93a] các thành phần đồ
họa (được gọi là "views") duy trì một danh sách các đối tượng "adorner" mà
có thể gắn thêm adornments như Border vào thành phần. Nếu một Lớp View
có bất kỳ adorners gắn vào, nó sẽ cho họ cơ hội để vẽ thêm embellishments.
MacApp và Bedrock phải sử dụng phương pháp này vì lớp View khá
nặng.Sẽ là quá tốn kém để sử dụng một Lớp View đầy đủ chính thức chỉ để
thêm một đường viền..
Kể từ khi các mô hình trang trí chỉ thay đổi một thành phần từ bên ngoài, các
thành phần không cần phải biết bất cứ điều gì về trang trí của nó; có nghĩa
là, các trang trí là trong suốt đối với các thành phần:
Với các chiến lược, các thành phần tự biết về các phần mở rộng có thể.. Vì
vậy, nó phải tham khảo và duy trì chiến lược tương ứng:
Chiến lược dựa trên phương pháp tiếp cận có thể yêu cầu sửa đổi các thành
phần để phù hợp với tiện ích mở rộng mới. Mặt khác, một chiến lược có thể
có giao diện đặc biệt của riêng của nó, trong khi một trang trí giao diện phải
phù hợp với các thành phần. Ví dụ một chiến lược để dựng một Border chỉ
cần xác định giao diện để vẽ một Border (DrawBorder, getWidth, vv), có
nghĩa là chiến lược có thể gọn nhẹ ngay cả khi các lớp thành phần là phức
tạp.
MacApp và Bedrock sử dụng cách tiếp cận này cho nhiều hơn là chỉ trang trí
Views. Họ cũng sử dụng nó để tăng cường hành vi xử lý sự kiện của các đối
tượng. Trong cả hai hệ thống, một Lớp Views quản lý một danh sách các đối
tượng "hành vi" mà có thể sửa đổi và chặn các sự kiện. Giao diện cho mỗi
một trong số các đối tượng đăng ký hành vi một cơ hội để xử lý các sự kiện
trước khi hành vi chưa đăng ký có hiệu quả thay thế chúng. ví dụ Bạn có thể
trang trí một View(giao diện) với hỗ trợ xử lý đặc biệtbằng cách đăng ký
một đối tượng hành vi đó mà chặn và xử lý các sự kiện quan trọng .
 Ví dụ
Các đoạn mã sau đây cho thấy thực hiện trang trí giao diện người dùng trong C ++
như thế nào. Chúng tôi sẽ giả sử có một lớp được gọi là VisualComponent
class VisualComponent {
public:
VisualComponent();
virtual void Draw();
virtual void Resize();
// ...
};
Chúng ta định nghĩa một lớp con của VisualComponent gọi Decorator, mà chúng
ta sẽ phân lớp để có được trang trí khác nhau
class Decorator : public VisualComponent {
public:
Decorator(VisualComponent*);
virtual void Draw();
virtual void Resize();
// ...
private:
VisualComponent* _component;
}
Decorator trang trí các VisualComponent tham chiếu bởi các biến thực thể
_component, được khởi tạo trong constructor. Đối với mỗi phương thức trong giao
diện của VisualComponent, Decorator định nghĩa một thực hiện mặc định mà vượt
qua các yêu cầu trên để _component:
void Decorator::Draw () {
_component->Draw();
}
void Decorator::Resize () {
_component->Resize();
}
Các lớp con của Decorator xác định trang trí cụ thể. Ví dụ, các lớp
BorderDecorator thêm một Border cho thành phần kèm theo của
nó. BorderDecorator là một lớp con của Decorator , sẽ ghi đè các phương thức
Draw để vẽ Border. BorderDecorator cũng xác định một phương thức DrawBorder
helper private thực hiện việc vẽ. Các lớp con kế thừa tất cả các phương thức khác
từ Decorator.
class BorderDecorator : public Decorator {
public:
BorderDecorator(VisualComponent*, int borderWidth);
virtual void Draw();
private:
void DrawBorder(int);
private:
int _width;
};
void BorderDecorator::Draw () {
Decorator::Draw();
DrawBorder(_width);
}
Một thực hiện tương tự sẽ làm theo cho ScrollDecorator và DropShadowDecorator,
ta sẽ thêm di chuyển và khả năng thả bóng cho một thành phần trực quan.
Bây giờ chúng ta có thể soạn các thực thể của các lớp này để cung cấp đồ các Mẫu
trang trí khác nhau. Các mã sau minh họa cách chúng ta có thể sử dụng trang trí để
tạo ra một TextView cuộn đã có viền và có thể cuộn.
Đầu tiên, chúng ta cần một cách để đặt một thành phần trực quan vào một đối
tượng cửa sổ. Chúng ta sẽ giả định lớp cửa sổ cung cấp một phương thức
SetContents cho mục đích này:
void Window::SetContents (VisualComponent* contents) {
// ...
}
Bây giờ chúng ta có thể tạo ra các văn bản hiển thị và một cửa sổ để đặt nó vào
trong:
Window* window = new Window;
TextView* textView = new TextView;
TextView là một VisualComponent, cho phép chúng ta đưa nó vào cửa sổ:
window->SetContents(textView);
Nhưng chúng ta muốn một TextView có Border và cuộn được. Vì vậy, chúng ta
trang trí nó cho phù hợp trước khi đặt nó trong cửa sổ.
window->SetContents(
new BorderDecorator(
new ScrollDecorator(textView), 1
)
);
Vì Window truy cập nội dung của nó thông qua giao diện VisualComponent, nó
không ý thức được sự có mặt của trang trí. Bạn, là khách hàng, vẫn có thể theo dõi
xem văn bản nếu bạn có thể tương tác trực tiếp với nó, ví dụ, khi bạn cần phải gọi
phương thức mà không phải là một phần của giao diện VisualComponent. Khách
hàng cũng có thể dựa trên danh tính của thành phần trực tiếp tham khảo từ nó.
Các ứng dụng được biết đến
Nhiều bộ công cụ giao diện người sử dụng hướng đối tượng sử dụng trang trí để
thêm đồ họa phần tô điểm cho widget. Ví dụ bao gồm InterViews [LVC98, LCI +
92], ET ++ [WGM88], và các OjectWorks  Smalltalk lớp thư viện [Par90]. Các
ứng dụng kỳ lạ của trang trí là DebuggingGlyph từ InterViews và
PassivityWrapper từ ParcPlace Smalltalk. Một DebuggingGlyph in ra thông tin gỡ
lỗi trước và sau khi chuyển tiếp một yêu cầu bố trí cho thành phần của nó. Việc lần
vết thông tin này có thể được sử dụng để phân tích và gỡ lỗi hành vi bố trí của các
đối tượng trong một thành phần phức tạp. Một PassivityWrapper có thể kích hoạt
hoặc vô hiệu hóa người dùng tương tác với các thành phần.
Nhưng các mô hình trang trí không có nghĩa là giới hạn đối với giao diện người
dùng đồ họa, như minh hoạ trong ví dụ sau (dựa trên ET ++ streaming classes
[WGM88]).
Streams là một khái niệm trừu tượng cơ bản trong hầu hết các cơ sở I / O. Một
luồng có thể cung cấp một giao diện để chuyển đổi các đối tượng vào một chuỗi
các byte hoặc ký tự. Điều đó cho phép chúng ta ghi lại một đối tượng vào một tập
tin hoặc một chuỗi trong bộ nhớ để thu hồi sau. Một cách đơn giản để làm điều này
là định nghĩa một lớp Stream trừu tượng với các lớp con MemoryStream và
FileStream. Nhưng giả sử chúng ta muốn có khả năng làm những việc sau:
 Nén dữ liệu dòng bằng cách sử dụng thuật toán nén khác nhau (run-length
encoding, Lempel-Ziv, vv.).
 Giảm dòng dữ liệu đến các ký tự ASCII 7-bit, do đó nó có thể được truyền
qua một kênh truyền thông ASCII
Các mô hình trang trí cho chúng ta một cách trang nhã(đơn giản) để thêm những
chức năng đối với Steam. Sơ đồ dưới đây cho thấy một giải pháp cho vấn đề:
Lớp trừu tượng Stream duy trì một bộ đệm nội bộ và cung cấp các phương thức để
lưu trữ dữ liệu vào các dòng (PutInt, PutString). Bất cứ khi nào các bộ đệm đầy ,
Stream gọi phương thức trừu tượng HandleBufferFull, thực hiện chuyển giao các
dữ liệu thực tế. Phiên bản FileStream của phương thức này sẽ thay thế này hoạt
động để chuyển bộ đệm vào một tập tin
Các lớp ở đây là StreamDecorator, trong đó duy trì một tham chiếu đến một steam
thành phần và chuyển tiếp yêu cầu đến nó. lớp con StreamDecorator chồng
chất(đè) lên HandleBufferFull và thực hiện các phương thưucs bổ sung trước khi
gọi phương thức HandleBufferFull của StreamDecorator.
Ví dụ, các lớp con CompressingStream nén dữ liệu, và các ASCII7Stream chuyển
đổi các dữ liệu vào 7-bit ASCII. Bây giờ, để tạo ra một FileStream mà nén dữ liệu
của nó và chuyển đổi các dữ liệu nhị phân để nén 7-bit ASCII, chúng ta trang trí
với một FileStream CompressingStream và một ASCII7Stream:
Stream* aStream = new CompressingStream(
new ASCII7Stream(
new FileStream("aFileName")
)
);
aStream->PutInt(12);
aStream->PutString("aString");
 Các mẫu liên quan
Adapter : Mẫu Decorator khác với Adapter, Decorator chỉ thay đổi nhiệm vụ của
đối tượng, không phải là thay đổi giao diện của nó như Adapter.Adapter sẽ mang
đến cho đối tượng một giao diện mới hoàn toàn.
Composit: Decorator cũng có thể coi như một Composite bị thoái hoá với duy nhất
một thành phần. Tuy nhiên, một Decorator thêm phần nhiệm phụ, nó là phần đối
tượng được kết tập vào.
Strategy: Một Decorator cho phép chúng ta thay đổi bề ngoài của một đối tượng,
một strategy cho phép chúng ta thay đổi ruột của đối tượng. Chúng là 2 cách luân
phiên nhau để ta thay đổi một đối tượng.
!

Más contenido relacionado

Destacado (20)

2 кл
2 кл2 кл
2 кл
 
Sample Photos
Sample PhotosSample Photos
Sample Photos
 
3 клас
 3 клас 3 клас
3 клас
 
-
--
-
 
Ppt ch11
Ppt ch11Ppt ch11
Ppt ch11
 
Personalisatie & ROI
Personalisatie & ROIPersonalisatie & ROI
Personalisatie & ROI
 
WHATSAPP MASIVO
WHATSAPP MASIVOWHATSAPP MASIVO
WHATSAPP MASIVO
 
Quality matters
Quality mattersQuality matters
Quality matters
 
Табір "Веселка"
Табір "Веселка"Табір "Веселка"
Табір "Веселка"
 
Ppt ch05
Ppt ch05Ppt ch05
Ppt ch05
 
Ppt ch01
Ppt ch01Ppt ch01
Ppt ch01
 
Табір "Подоляночка"
Табір  "Подоляночка" Табір  "Подоляночка"
Табір "Подоляночка"
 
Olutionmanual microprocessorsand interfacing-dv-hall
Olutionmanual microprocessorsand interfacing-dv-hallOlutionmanual microprocessorsand interfacing-dv-hall
Olutionmanual microprocessorsand interfacing-dv-hall
 
5 клас
5 клас5 клас
5 клас
 
Табір "Веселка"
Табір "Веселка"Табір "Веселка"
Табір "Веселка"
 
นายศูภานุพงษ์ พานิชวัฒนะ ม4/12 เลขที่ 26
นายศูภานุพงษ์    พานิชวัฒนะ   ม4/12  เลขที่ 26นายศูภานุพงษ์    พานิชวัฒนะ   ม4/12  เลขที่ 26
นายศูภานุพงษ์ พานิชวัฒนะ ม4/12 เลขที่ 26
 
Researching genre
Researching genreResearching genre
Researching genre
 
Spanish 2
Spanish 2Spanish 2
Spanish 2
 
херсон
херсонхерсон
херсон
 
3 клас
3 клас3 клас
3 клас
 

Similar a Decorator

Lập trình hướng đối tượng Chương 6 Design Pattern.pptx
Lập trình hướng đối tượng Chương 6 Design Pattern.pptxLập trình hướng đối tượng Chương 6 Design Pattern.pptx
Lập trình hướng đối tượng Chương 6 Design Pattern.pptxLmTrn286060
 
Lập trình hướng đối tượng Chương 6 Design Pattern.pptx
Lập trình hướng đối tượng Chương 6 Design Pattern.pptxLập trình hướng đối tượng Chương 6 Design Pattern.pptx
Lập trình hướng đối tượng Chương 6 Design Pattern.pptxLmTrn286060
 
IT120-3. Thiết kế giao diện trên Android
IT120-3. Thiết kế giao diện trên AndroidIT120-3. Thiết kế giao diện trên Android
IT120-3. Thiết kế giao diện trên AndroidMultiUni
 
Tài liệu Lập trình Zend Framework 2.x
Tài liệu Lập trình Zend Framework 2.xTài liệu Lập trình Zend Framework 2.x
Tài liệu Lập trình Zend Framework 2.xZendVN
 
Bài 2 - Trang Web Giới Thiệu (2).docx
Bài 2 - Trang Web Giới Thiệu (2).docxBài 2 - Trang Web Giới Thiệu (2).docx
Bài 2 - Trang Web Giới Thiệu (2).docxTrongNguyn1
 
Bg ngonngulaptrinh c++
Bg ngonngulaptrinh c++Bg ngonngulaptrinh c++
Bg ngonngulaptrinh c++Cu Chuần
 
Trong bài viết hôm nay
Trong bài viết hôm nayTrong bài viết hôm nay
Trong bài viết hôm nayledoanduc
 
Hướng Dẫn Lập Trình Android: 3. Thiet ke giao dien tren Android
Hướng Dẫn Lập Trình Android: 3. Thiet ke giao dien tren AndroidHướng Dẫn Lập Trình Android: 3. Thiet ke giao dien tren Android
Hướng Dẫn Lập Trình Android: 3. Thiet ke giao dien tren AndroidWendy587439
 
Slide bài giảng lập trình Android DTU - Phần 2 (Thiết kế giao diện)
Slide bài giảng lập trình Android DTU - Phần 2 (Thiết kế giao diện)Slide bài giảng lập trình Android DTU - Phần 2 (Thiết kế giao diện)
Slide bài giảng lập trình Android DTU - Phần 2 (Thiết kế giao diện)Techacademy Software
 
Một số lệnh tắt trong auto cad và những lệnh hay trong autocad
Một số lệnh tắt trong auto cad và những lệnh hay trong autocadMột số lệnh tắt trong auto cad và những lệnh hay trong autocad
Một số lệnh tắt trong auto cad và những lệnh hay trong autocadTrung Lưu
 
3.thiet ke giao dien tren android
3.thiet ke giao dien tren android3.thiet ke giao dien tren android
3.thiet ke giao dien tren androidJustin Hoang
 
Sức mạnh của jsf 2, phần 2 tạo khuôn mẫu và các thành phần phức hợp
Sức mạnh của jsf 2, phần 2 tạo khuôn mẫu và các thành phần phức hợpSức mạnh của jsf 2, phần 2 tạo khuôn mẫu và các thành phần phức hợp
Sức mạnh của jsf 2, phần 2 tạo khuôn mẫu và các thành phần phức hợpTuyet Tam
 
Chuong9 lop vadoituong
Chuong9 lop vadoituongChuong9 lop vadoituong
Chuong9 lop vadoituongMinh Ngoc Tran
 
Thương mại điện tử
Thương  mại điện tửThương  mại điện tử
Thương mại điện tửgacon2009
 

Similar a Decorator (20)

Lập trình hướng đối tượng Chương 6 Design Pattern.pptx
Lập trình hướng đối tượng Chương 6 Design Pattern.pptxLập trình hướng đối tượng Chương 6 Design Pattern.pptx
Lập trình hướng đối tượng Chương 6 Design Pattern.pptx
 
Lập trình hướng đối tượng Chương 6 Design Pattern.pptx
Lập trình hướng đối tượng Chương 6 Design Pattern.pptxLập trình hướng đối tượng Chương 6 Design Pattern.pptx
Lập trình hướng đối tượng Chương 6 Design Pattern.pptx
 
IT120-3. Thiết kế giao diện trên Android
IT120-3. Thiết kế giao diện trên AndroidIT120-3. Thiết kế giao diện trên Android
IT120-3. Thiết kế giao diện trên Android
 
Tài liệu Lập trình Zend Framework 2.x
Tài liệu Lập trình Zend Framework 2.xTài liệu Lập trình Zend Framework 2.x
Tài liệu Lập trình Zend Framework 2.x
 
Entercad.edu.vn
Entercad.edu.vnEntercad.edu.vn
Entercad.edu.vn
 
Bài 2 - Trang Web Giới Thiệu (2).docx
Bài 2 - Trang Web Giới Thiệu (2).docxBài 2 - Trang Web Giới Thiệu (2).docx
Bài 2 - Trang Web Giới Thiệu (2).docx
 
Bg ngonngulaptrinh c++
Bg ngonngulaptrinh c++Bg ngonngulaptrinh c++
Bg ngonngulaptrinh c++
 
Mvc 3
Mvc 3Mvc 3
Mvc 3
 
Chuong 09 thua ke
Chuong 09 thua keChuong 09 thua ke
Chuong 09 thua ke
 
Tai lieu etabs 2013
Tai lieu etabs 2013Tai lieu etabs 2013
Tai lieu etabs 2013
 
Trong bài viết hôm nay
Trong bài viết hôm nayTrong bài viết hôm nay
Trong bài viết hôm nay
 
Hướng Dẫn Lập Trình Android: 3. Thiet ke giao dien tren Android
Hướng Dẫn Lập Trình Android: 3. Thiet ke giao dien tren AndroidHướng Dẫn Lập Trình Android: 3. Thiet ke giao dien tren Android
Hướng Dẫn Lập Trình Android: 3. Thiet ke giao dien tren Android
 
Slide bài giảng lập trình Android DTU - Phần 2 (Thiết kế giao diện)
Slide bài giảng lập trình Android DTU - Phần 2 (Thiết kế giao diện)Slide bài giảng lập trình Android DTU - Phần 2 (Thiết kế giao diện)
Slide bài giảng lập trình Android DTU - Phần 2 (Thiết kế giao diện)
 
Một số lệnh tắt trong auto cad và những lệnh hay trong autocad
Một số lệnh tắt trong auto cad và những lệnh hay trong autocadMột số lệnh tắt trong auto cad và những lệnh hay trong autocad
Một số lệnh tắt trong auto cad và những lệnh hay trong autocad
 
3.thiet ke giao dien tren android
3.thiet ke giao dien tren android3.thiet ke giao dien tren android
3.thiet ke giao dien tren android
 
Sức mạnh của jsf 2, phần 2 tạo khuôn mẫu và các thành phần phức hợp
Sức mạnh của jsf 2, phần 2 tạo khuôn mẫu và các thành phần phức hợpSức mạnh của jsf 2, phần 2 tạo khuôn mẫu và các thành phần phức hợp
Sức mạnh của jsf 2, phần 2 tạo khuôn mẫu và các thành phần phức hợp
 
Chuong9 lop vadoituong
Chuong9 lop vadoituongChuong9 lop vadoituong
Chuong9 lop vadoituong
 
Bai11 ooad bieu_dolop
Bai11 ooad bieu_dolopBai11 ooad bieu_dolop
Bai11 ooad bieu_dolop
 
Thương mại điện tử
Thương  mại điện tửThương  mại điện tử
Thương mại điện tử
 
Vb6 16 (1)
Vb6 16 (1)Vb6 16 (1)
Vb6 16 (1)
 

Decorator

  • 1. MẪU TRANG TRÍ Mục đích Gắn các chức năng bổ sung cho các đối tượng (gán động). Decorator cung cấp một số thay đổi mềm dẻo cho các phân lớp để mở rộng thêm các chức năng. Còn được biết đến là Phương pháp "Đóng gói" Động cơ Đôi khi chúng ta muốn thêm các chức năng cho các đối tượng riêng lẻ , chứ không phải cho toàn bộ một lớp. Ví dụ một bộ giao diện người dùng công cụ đồ họa, sẽ cho phép bạn thêm các thuộc tính như Border (viền) hoặc các hành vi như di chuyển đến bất kỳ giao diện người sử dụng thành phần nào. Một cách để thêm chức năng là sử dụng Thừa kế. Kế thừa một Border từ một lớp khác , đặt Border trong mỗi thực thể của lớp con. Cách này không linh hoạt, tuy nhiên, vì ta chọn việc thiết lập các Border là tĩnh. Một người dùng không thể kiểm soát việc tùy chỉnh các thành phần với Border khi nào và như thế nào. Một cách tiếp cận linh hoạt hơn là đính kèm theo các thành phần trong một đối tượng khác có thêm Border. Đối tượng này được gán thêm này gọi là Decorator. Các Decoratror phù hợp với giao diện của các thành phần mà nó trang trí để thể hiện của nó là (rõ ràng) minh bạch với người sử dụng. Các Decorator gửi yêu cầu đến các thành phần để có thể thực hiện các hành động bổ sung (như vẽ một đường viền) trước hoặc sau khi giao nhận. Việc Minh bạch hoá cho phép bạn tổ chức trang trí đệ quy, do đó cho phép thêm một số lượng không giới hạn các chức năng.
  • 2. Ví dụ, giả sử chúng ta có một đối tượng TextView hiển thị văn bản trong một cửa sổ. TextView không có thanh cuộn theo mặc định, bởi vì chúng ta có thể ko phải lúc nào cũng cần đến chúng. Khi chúng ta làm, chúng ta có thể sử dụng một Scroll Decorator để thêm vào. Giả sử chúng ta cũng muốn thêm một đường viền màu đen dày quanh TextView. chúng ta cũng có thể sử dụng một Decorator Border để thêm vào. Chúng ta chỉ đơn giản là soạn các trang trí với TextView để tạo các kết quả mong muốn. Các sơ đồ đối tượng sau đây cho thấy làm thế nào để tạo ra một đối tượng TextView với đối tượng Border Decorator và Scroll Decorator để tạo ra một Border ( đường viền), và thanh cuộn xem văn bản:
  • 3. Các lớp Scroll Decorator và Border Decorator là lớp con của Decorator, một lớp trừu tượng cho các thành phần trực quan để trang trí các thành phần trực quan khác. VisualComponent (thành phần trực quan) là lớp trừu tượng cho các đối tượng trực quan. Nó định nghĩa bản vẽ và xử lý sự kiện trong giao diện. Lưu ý các lớp Decorator chỉ đơn giản chuyển tiếp yêu cầu vẽ cho các thành phần của nó, và làm thế nào các lớp con của Decorator có thể mở rộng hoạt động này Các Lớp con của Decorator được thêm các hoạt động cho các chức năng cụ thể một cách thoải mái. Ví dụ, hoạt động ScrollTo của Decorator cho phép các đối tượng khác di chuyển các giao diện nếu họ biết những thứ diễn ra là một đối tượng ScrollDecorator trong giao diện. Các khía cạnh quan trọng của mô hình này là nó cho phép Các mẫu trang trí (decorator) xuất hiện bất cứ nơi nào một thành phần trực quan (VisualComponent) xuất hiện. Đó là cách người dùng thông thường không thể biết sự khác biệt giữa một thành phần trang trí và một thành phần không trang trí, và vì vậy chúng không phụ thuộc vào tất cả các trang trí phía trên.
  • 4. Ứng dụng Sử dụng Decorator khi:  Thêm các chức năng bổ sung cho các đối tượng riêng biệt một cách động và trong suốt, nghĩa là không chịu ảnh hưởng (tác động ) của các đối tượng khác.  Cho các chức năng mà các chức năng này có thể được rút lại (hủy bỏ) (nếu không cần nữa).  Khi sự mở rộng được thực hiện bởi các phân lớp là không thể thực hiện được. Đôi khi một lượng lớn các mở rộng độc lập có thể thực hiện được nhưng lại tạo ra một sự bùng nổ các phân lớp để trợ giúp cho các kết hợp. Hoặc một định nghĩa lớp có thể bị che đi hay nói cách khác nó không có giá trị cho việc phân lớp. ....
  • 5. Cấu trúc Các thành phần  Component o Định nghĩa giao diện cho đối tượng mà có thể có các chức năng thêm vào nó vào một cách tự động  ConcreteComponent o Định nghĩa một đối tượng để có thể gắn thêm chức năng vào thành phần cho nó  Decorator o Duy trì một tham chiếu tới một đối tượng thành phần và định nghĩa một giao diện mà phù hợp với giao diện của thành phần.  ConcreteDecorator o Thêm nhiệm vụ cho thành phần !
  • 6. Sự tương tác Decorator chuyển tiếp yêu cầu đến đối tượng thành phần của nó. Nó có thể tùy chọn thực hiện các hoạt động bổ sung trước hoặc sau khi chuyển tiếp yêu cầu ! Hệ quả Các mô hình trang trí có ít nhất hai lợi ích quan trọng và 2 nhược điểm: 1. Linh hoạt hơn là thừa kế tĩnh. Các mẫu trang trí cung cấp một cách linh hoạt hơn để thêm chức năng cho các đối tượng có thể có nhiều các thừa kế tĩnh. Với trang trí, các chức năng có thể được thêm vào và lấy ra trong thời gian chạy chỉ đơn giản bằng cách gắn và tách chúng. Ngược lại, thừa kế đòi hỏi phải tạo ra một lớp mới cho mỗi lần thêm tính năng (ví dụ, BorderedScrollableTextView, BorderedTextView). Điều này dẫn đến có nhiều class và làm tăng sự phức tạp của một hệ thống. Hơn nữa, cung cấp các lớp trang trí khác nhau cho một thành phần cụ thể của lớp cho phép bạn pha trộn và làm phù hợp với chức năng Trang trí cũng làm cho nó dễ dàng để thêm một thuộc tính hai lần. Ví dụ, để cung cấp cho một TextView một viền đôi, chỉ cần đính kèm hai Border trang trí. Kế thừa từ một lớp Border hai lần là lúc dễ bị lỗi nhất 2. Để tránh các Lớp bị đầy tính năng cao cấp trong các hệ thống phân cấp. Decorator cung cấp một phương pháp tiếp cận pay-as-you-go(chi trả tùy khả năng ) để thêm chức năng. Thay vì cố gắng để hỗ trợ tất cả các tính năng có thể dự đoán trong một phức tạp, tùy lớp, bạn có thể định nghĩa một lớp đơn giản và thêm chức năng từng bước với Decorator đối tượng. Chức năng có thể được tạo ra từ những mảnh đơn giản. Kết quả là, một ứng dụng không cần phải chi trả(pay) cho các tính năng nó không sử dụng. Nó cũng dễ dàng để xác định các loại mới về trang trí độc lập với các lớp của các đối
  • 7. tượng mở rộng, ngay cả đối với các phần mở rộng không lường trước được. Mở rộng một lớp phức tạp có xu hướng để lộ các chi tiết liên quan đến chức năng mà bạn đang thêm 3. Một trang trí và thành phần của nó không giống nhau. Một hành vi trang trí như một vỏ bọc trong suốt. Nhưng từ một cái nhìn nhận dạng đối tượng, một thành phần trang trí không đồng nhất với các thành phần của chính nó. Do đó bạn không nên dựa vào nhận dạng đối tượng khi bạn sử dụng trang trí. 4. Rất nhiều đối tượng nhỏ. Một thiết kế có sử dụng Decorator thường cho ra kết quả là trong hệ thống có nhiều đối tượng nhỏ mà gần như tất cả giống nhau. Các đối tượng khác nhau chỉ ở cách chúng liên kết với nhau, không ở trong lớp hoặc trong các giá trị của các biến của chúng. Mặc dù các hệ thống này dễ dàng tuỳ biến bởi những người hiểu biết, họ có thể gặp khó khăn để tìm hiểu và gỡ lỗi !
  • 8.  Thực hiện Một số vấn đề cần được xem xét khi áp dụng các mô hình trang trí - Decorator pattern: 1. Giao diện phù hợp. Giao diện của một đối tượng trang trí phải phù hợp với giao diện của các thành phần nó trang trí. Do đó các lớp ConcreteDecorator phải kế thừa từ một lớp thông thường (ít nhất là trong C ++). 2. Bỏ qua các lớp Decorator trừu tượng. Không cần phải xác định một lớp Decorator trừu tượng khi bạn chỉ cần thêm một chức năng. Đó là trường hợp thường khi bạn đang làm việc với hệ thống lớp hiện thời hơn là thiết kế một cái mới. Trong trường hợp đó, bạn có thể kết hợp chức năng của Decorator để chuyển tiếp yêu cầu đến thành phần vào trong ConcreteDecorator. 3. Giữ các lớp Component gọn nhẹ. Để đảm bảo một giao diện phù hợp, các thành phần và các trang trí phải giảm xuống từ một lớp thông thường. Điều này là quan trọng là để giữ cho lớp này gọn nhẹ; nghĩa là, nó nên tập trung vào việc xác định một giao diện, không lưu trữ dữ liệu. Định nghĩa của các biểu diễn dữ liệu nên được hoãn lại đến lớp con; nếu không thì sự phức tạp của các lớp có thể làm cho các trang trí quá nặng để sử dụng với số lượng lớn. Đặt rất nhiều chức năng vào các thành phần cũng làm tăng xác suất mà lớp con sẽ phải trả cho tính năng mà chúng không cần. 4. Thay đổi bề ngoài (Skin) của một đối tượng so với thay đổi cốt lõi(ruột) của nó. Chúng ta có thể nghĩ về một trang trí như một lớp da ở một vật thể mà thay đổi hành vi của nó. Một giải pháp thay thế là để thay đổi phần cốt lõi (ruột) của đối tượng. Strategy (349) là một ví dụ của một mô hình để thay đổi ruột. Chiến lược(strategy) là một lựa chọn tốt hơn trong các tình huống mà các lớp có bản chất nặng(phức tạp), do đó làm cho các mô hình trang trí quá tốn kém để áp dụng. Trong các mô hình chiến lược, các thành phần chuyển tiếp một số hành vi của mình cho một đối tượng chiến lược riêng biệt (độc lập). Các mô hình chiến lược cho phép chúng ta thay đổi hay mở rộng chức năng của các thành phần bằng cách thay thế các đối tượng Strategy(chiến lược).
  • 9. Ví dụ, chúng ta có thể hỗ trợ các kiểu Border khác nhau bởi có 1 thành phần Vẽ Border độc lập với đối tượng Border. Các đối tượng Border là một đối tượng Strategy mà bao hàm một Strategy ( chiến lược) Vẽ Border. Bằng cách mở rộng số lượng các chiến lược từ một đến một danh sách mở, chúng ta đạt được hiệu quả tương tự như trang trí đệ quy. Ví dụ, Trong MacApp 3.0 [App89] và Bedrock [Sym93a] các thành phần đồ họa (được gọi là "views") duy trì một danh sách các đối tượng "adorner" mà có thể gắn thêm adornments như Border vào thành phần. Nếu một Lớp View có bất kỳ adorners gắn vào, nó sẽ cho họ cơ hội để vẽ thêm embellishments. MacApp và Bedrock phải sử dụng phương pháp này vì lớp View khá nặng.Sẽ là quá tốn kém để sử dụng một Lớp View đầy đủ chính thức chỉ để thêm một đường viền.. Kể từ khi các mô hình trang trí chỉ thay đổi một thành phần từ bên ngoài, các thành phần không cần phải biết bất cứ điều gì về trang trí của nó; có nghĩa là, các trang trí là trong suốt đối với các thành phần: Với các chiến lược, các thành phần tự biết về các phần mở rộng có thể.. Vì vậy, nó phải tham khảo và duy trì chiến lược tương ứng:
  • 10. Chiến lược dựa trên phương pháp tiếp cận có thể yêu cầu sửa đổi các thành phần để phù hợp với tiện ích mở rộng mới. Mặt khác, một chiến lược có thể có giao diện đặc biệt của riêng của nó, trong khi một trang trí giao diện phải phù hợp với các thành phần. Ví dụ một chiến lược để dựng một Border chỉ cần xác định giao diện để vẽ một Border (DrawBorder, getWidth, vv), có nghĩa là chiến lược có thể gọn nhẹ ngay cả khi các lớp thành phần là phức tạp. MacApp và Bedrock sử dụng cách tiếp cận này cho nhiều hơn là chỉ trang trí Views. Họ cũng sử dụng nó để tăng cường hành vi xử lý sự kiện của các đối tượng. Trong cả hai hệ thống, một Lớp Views quản lý một danh sách các đối tượng "hành vi" mà có thể sửa đổi và chặn các sự kiện. Giao diện cho mỗi một trong số các đối tượng đăng ký hành vi một cơ hội để xử lý các sự kiện trước khi hành vi chưa đăng ký có hiệu quả thay thế chúng. ví dụ Bạn có thể trang trí một View(giao diện) với hỗ trợ xử lý đặc biệtbằng cách đăng ký một đối tượng hành vi đó mà chặn và xử lý các sự kiện quan trọng .
  • 11.  Ví dụ Các đoạn mã sau đây cho thấy thực hiện trang trí giao diện người dùng trong C ++ như thế nào. Chúng tôi sẽ giả sử có một lớp được gọi là VisualComponent class VisualComponent { public: VisualComponent(); virtual void Draw(); virtual void Resize(); // ... }; Chúng ta định nghĩa một lớp con của VisualComponent gọi Decorator, mà chúng ta sẽ phân lớp để có được trang trí khác nhau class Decorator : public VisualComponent { public: Decorator(VisualComponent*); virtual void Draw(); virtual void Resize(); // ... private: VisualComponent* _component; } Decorator trang trí các VisualComponent tham chiếu bởi các biến thực thể _component, được khởi tạo trong constructor. Đối với mỗi phương thức trong giao diện của VisualComponent, Decorator định nghĩa một thực hiện mặc định mà vượt qua các yêu cầu trên để _component: void Decorator::Draw () { _component->Draw();
  • 12. } void Decorator::Resize () { _component->Resize(); } Các lớp con của Decorator xác định trang trí cụ thể. Ví dụ, các lớp BorderDecorator thêm một Border cho thành phần kèm theo của nó. BorderDecorator là một lớp con của Decorator , sẽ ghi đè các phương thức Draw để vẽ Border. BorderDecorator cũng xác định một phương thức DrawBorder helper private thực hiện việc vẽ. Các lớp con kế thừa tất cả các phương thức khác từ Decorator. class BorderDecorator : public Decorator { public: BorderDecorator(VisualComponent*, int borderWidth); virtual void Draw(); private: void DrawBorder(int); private: int _width; }; void BorderDecorator::Draw () { Decorator::Draw(); DrawBorder(_width); } Một thực hiện tương tự sẽ làm theo cho ScrollDecorator và DropShadowDecorator, ta sẽ thêm di chuyển và khả năng thả bóng cho một thành phần trực quan. Bây giờ chúng ta có thể soạn các thực thể của các lớp này để cung cấp đồ các Mẫu trang trí khác nhau. Các mã sau minh họa cách chúng ta có thể sử dụng trang trí để tạo ra một TextView cuộn đã có viền và có thể cuộn.
  • 13. Đầu tiên, chúng ta cần một cách để đặt một thành phần trực quan vào một đối tượng cửa sổ. Chúng ta sẽ giả định lớp cửa sổ cung cấp một phương thức SetContents cho mục đích này: void Window::SetContents (VisualComponent* contents) { // ... } Bây giờ chúng ta có thể tạo ra các văn bản hiển thị và một cửa sổ để đặt nó vào trong: Window* window = new Window; TextView* textView = new TextView; TextView là một VisualComponent, cho phép chúng ta đưa nó vào cửa sổ: window->SetContents(textView); Nhưng chúng ta muốn một TextView có Border và cuộn được. Vì vậy, chúng ta trang trí nó cho phù hợp trước khi đặt nó trong cửa sổ. window->SetContents( new BorderDecorator( new ScrollDecorator(textView), 1 ) ); Vì Window truy cập nội dung của nó thông qua giao diện VisualComponent, nó không ý thức được sự có mặt của trang trí. Bạn, là khách hàng, vẫn có thể theo dõi xem văn bản nếu bạn có thể tương tác trực tiếp với nó, ví dụ, khi bạn cần phải gọi phương thức mà không phải là một phần của giao diện VisualComponent. Khách hàng cũng có thể dựa trên danh tính của thành phần trực tiếp tham khảo từ nó.
  • 14. Các ứng dụng được biết đến Nhiều bộ công cụ giao diện người sử dụng hướng đối tượng sử dụng trang trí để thêm đồ họa phần tô điểm cho widget. Ví dụ bao gồm InterViews [LVC98, LCI + 92], ET ++ [WGM88], và các OjectWorks Smalltalk lớp thư viện [Par90]. Các ứng dụng kỳ lạ của trang trí là DebuggingGlyph từ InterViews và PassivityWrapper từ ParcPlace Smalltalk. Một DebuggingGlyph in ra thông tin gỡ lỗi trước và sau khi chuyển tiếp một yêu cầu bố trí cho thành phần của nó. Việc lần vết thông tin này có thể được sử dụng để phân tích và gỡ lỗi hành vi bố trí của các đối tượng trong một thành phần phức tạp. Một PassivityWrapper có thể kích hoạt hoặc vô hiệu hóa người dùng tương tác với các thành phần. Nhưng các mô hình trang trí không có nghĩa là giới hạn đối với giao diện người dùng đồ họa, như minh hoạ trong ví dụ sau (dựa trên ET ++ streaming classes [WGM88]). Streams là một khái niệm trừu tượng cơ bản trong hầu hết các cơ sở I / O. Một luồng có thể cung cấp một giao diện để chuyển đổi các đối tượng vào một chuỗi các byte hoặc ký tự. Điều đó cho phép chúng ta ghi lại một đối tượng vào một tập tin hoặc một chuỗi trong bộ nhớ để thu hồi sau. Một cách đơn giản để làm điều này là định nghĩa một lớp Stream trừu tượng với các lớp con MemoryStream và FileStream. Nhưng giả sử chúng ta muốn có khả năng làm những việc sau:  Nén dữ liệu dòng bằng cách sử dụng thuật toán nén khác nhau (run-length encoding, Lempel-Ziv, vv.).  Giảm dòng dữ liệu đến các ký tự ASCII 7-bit, do đó nó có thể được truyền qua một kênh truyền thông ASCII Các mô hình trang trí cho chúng ta một cách trang nhã(đơn giản) để thêm những chức năng đối với Steam. Sơ đồ dưới đây cho thấy một giải pháp cho vấn đề:
  • 15. Lớp trừu tượng Stream duy trì một bộ đệm nội bộ và cung cấp các phương thức để lưu trữ dữ liệu vào các dòng (PutInt, PutString). Bất cứ khi nào các bộ đệm đầy , Stream gọi phương thức trừu tượng HandleBufferFull, thực hiện chuyển giao các dữ liệu thực tế. Phiên bản FileStream của phương thức này sẽ thay thế này hoạt động để chuyển bộ đệm vào một tập tin Các lớp ở đây là StreamDecorator, trong đó duy trì một tham chiếu đến một steam thành phần và chuyển tiếp yêu cầu đến nó. lớp con StreamDecorator chồng chất(đè) lên HandleBufferFull và thực hiện các phương thưucs bổ sung trước khi gọi phương thức HandleBufferFull của StreamDecorator. Ví dụ, các lớp con CompressingStream nén dữ liệu, và các ASCII7Stream chuyển đổi các dữ liệu vào 7-bit ASCII. Bây giờ, để tạo ra một FileStream mà nén dữ liệu của nó và chuyển đổi các dữ liệu nhị phân để nén 7-bit ASCII, chúng ta trang trí với một FileStream CompressingStream và một ASCII7Stream: Stream* aStream = new CompressingStream( new ASCII7Stream( new FileStream("aFileName") ) ); aStream->PutInt(12);
  • 16. aStream->PutString("aString");  Các mẫu liên quan Adapter : Mẫu Decorator khác với Adapter, Decorator chỉ thay đổi nhiệm vụ của đối tượng, không phải là thay đổi giao diện của nó như Adapter.Adapter sẽ mang đến cho đối tượng một giao diện mới hoàn toàn. Composit: Decorator cũng có thể coi như một Composite bị thoái hoá với duy nhất một thành phần. Tuy nhiên, một Decorator thêm phần nhiệm phụ, nó là phần đối tượng được kết tập vào. Strategy: Một Decorator cho phép chúng ta thay đổi bề ngoài của một đối tượng, một strategy cho phép chúng ta thay đổi ruột của đối tượng. Chúng là 2 cách luân phiên nhau để ta thay đổi một đối tượng. !