概念:標準的裝飾模式有包括一個抽象的Component父類袖扛,它聲明了一些操作,它具體的類講進行重載以實現(xiàn)自己特定的操作。這個Component具體類是模式中的被裝飾者卷扮,Component父類可以被細化為另一個叫做Decorator的抽象類荡碾,即裝飾者抽象類谨读。Decorator類中包含了一個Component的引用。Decorator的具體類為Component或者Decorator定義了幾個擴展行為坛吁,并且會在自己的操作中內(nèi)嵌Component操作劳殖。關(guān)系圖見 裝飾模式類圖
Component定義了一些抽象操作铐尚,具體類將進行重載實現(xiàn)自己特定的操作。Decorator抽象類通過將一個Component(或Decorator)內(nèi)嵌到Decorator對象哆姻,定義了擴展這個Component的實例的“裝飾性”的行為宣增。默認的operation方法只是想內(nèi)嵌的Component發(fā)送一個消息,Decorator的具體實現(xiàn)類重載父類的operation填具,通過super把自己增加的行為擴展給Component的operation统舀。如果只需要向Component添加一種職責,那可以省掉抽象的Decorator類劳景,讓具體的Decorator直接把請求轉(zhuǎn)發(fā)給Component誉简。那么這種方式就好像形成一種操作鏈,把一種行為加到另一種行為之上盟广。
2.裝飾者模式概念圖
裝飾模式使用場景
想要在不影響其他對象的情況下闷串,以動態(tài)、透明的方式給單個對象添加職責筋量。想要擴展一個類的行為烹吵,卻做不到。類定義可能被隱藏桨武,無法進行子類化肋拔;或者對類的每個行為的擴展,為支持每種功能組合呀酸,將產(chǎn)生大量的子類凉蜂,對類的職責的擴展是可選的。
1.當系統(tǒng)需要新功能時性誉,向舊類中添加新的代碼窿吩,這些新代碼只是裝飾了原有類的核心職責,并沒有替換掉原有類的核心職責错览。新的字段纫雁、方法和邏輯增加了原有類的復雜度。這些新加入的東西僅僅是為了滿足一些只在某種特定情況下才執(zhí)行的特殊需要倾哺,不必加入原有類轧邪,增加復雜度。
2.裝飾者模式提供了一個非常好的解決方案羞海,它把每個要裝飾的功能放在單獨的類當中忌愚,并讓這個類包裝它所要裝飾的對象。當需要執(zhí)行特殊行為時扣猫,viewController 中的代碼就可以在運行時根據(jù)需要有選擇、按順序地使用裝飾對象了翘地。
3.裝飾模式可以把類中的裝飾功能去除申尤,簡化類癌幕,有效區(qū)分核心職責和裝飾功能,去除相關(guān)類中重復的裝飾邏輯昧穿。
使用案例:
一個女孩需要出席一場晚會勺远,這個時候需要盛裝打扮下自己。使用裝飾者模式就再好不過了时鸵。
首先定義一個類胶逢,這個類是要出席晚會的girl,被裝飾對象。
實現(xiàn)代碼細節(jié)
@interface Girl : NSObject
代表名字
@property (nonatomic, strong) NSString *name;
//穿的裝飾品
- (void)show;
@end
//展示自己穿了什么衣服
- (void)show{
NSLog(@"%@",self.name);
}
- (void)setName:(NSString *)name{
_name = name;
}
在定義一個裝飾類Finery 類 其實就是 Decorator 類(裝飾抽象類)
#import "Girl.h"
@class Girl;
@interface Finery : Girl;
@property(nonatomic,strong)Girl *component;
@end
#import "Finery.h"
@implementation Finery
- (void)show{
if (self.component!= nil) {
[self.component show];
}
}
- (void)setComponent:(Girl *)component{
_component = component;
}
@end
然后就可以定義具體的類饰潜,比如衣服初坠,鞋子,褲子彭雾。去擴展裝飾對象碟刺,修飾裝飾對象。
#import "Finery.h"
@interface Shoes : Finery
@end
#import "Shoes.h"
@implementation Shoes
- (void)show{
[super show];
NSLog(@"鞋子");
}
@end
具體調(diào)用方式
- (void)viewDidLoad {
[super viewDidLoad];
self.navigationController.title = @"裝飾者模式";
Girl *girl = [[Girl alloc] init];
girl.name = @"james";
Shoes *shoe = [Shoes new];
shoe.component = girl;
[shoe show];
}
實現(xiàn)結(jié)果
分析實現(xiàn)過程:
Finery 不會被直接使用薯酝,而是作為具體裝飾類的父類存在半沽。具體服飾類,就是Shoes 這些類吴菠,這些類需要在調(diào)用父類 show 方法的同時實現(xiàn)自己特有的方法者填。首先,創(chuàng)建的girl對象給name賦值為james,然后創(chuàng)建shoe對象做葵,設置shoe的component = girl占哟,然后調(diào)用[shoe show];來到show方法內(nèi)部 執(zhí)行 NSLog(@"鞋子");
[super show];會來到父類也就是裝飾類Finery中調(diào)用
- (void)show{
if (self.component!= nil) {
[self.component show];
}
}
由于self.component是Girl類型,所以會執(zhí)行Girl內(nèi)部的show方法輸出James.