常用設計模式
責任鏈,橋接模式,適配器模式,單例模式,命令模式
六大設計原則
1.單一職責原則
一個類只負責一件事(CALayer,和UIView)
2.開閉原則
對修改關閉,對拓展開放(分類文件)
3.接口隔離原則
使用多個專門的協議,而不是龐大臃腫協議(tableview的DataSource和Delegate)
4.依賴倒置原則
抽象不應該依賴具體實現,具體實現可以依賴抽象(通過抽象接口,增刪改查的緩存方案)。
5.里氏替換原則:
父類可以被子類無縫替換,且原有功能不受影響(KVO動態生成NSKVONotying)
6.迪米特法則
一個對象應當對其他對象有盡可能少的了解-高內聚,低耦合。
責任鏈模式(鏈條中的對象兩個類是一樣的)
-
應用場景
image.png
解決需求變更順序的設計方案,需求變更只需要改為變更指向,系統中的UI響應鏈(UIResponder)
實現:某一對象或者類,也是自身類的成員變量。A類:A類中的成員變量有一個A類型的next變量(下一個響應者)
提供了兩個方法:一個是響應者的處理方法:入口函數,另一個是業務處理Handler。
具體代碼:
橋接模式
橋接類的構成:
A1:B1,B2,B3
A2:B1,B2,B3
A3:B1,B2,B3
3個不同的業務A列表就可應對不同的B的網絡請求。
-
具體實現代碼
image.png
具體的業務類A1, B1重寫不同父類的方法即可。
具體調用運用:(聲明不同BaseA和BaseB的子類,完成了業務的解耦)
適配器模式
一個現有類需要適應變化的問題?(對原有類進行適配功能)
對象適配器,類適配器。
具體代碼:
單例模式
完整的單例模式需要重寫allocWithZone和copyWithzone,為了規避這兩種方法創建。
單例中的調用是 [[super allocWithZone:NULL]init]
命令模式
對一些重合度搞的代碼,進行行為參數化,用來降低代碼重合度(比如分享,轉發,跳轉)
Commend類
Command類中具體的實現(指令執行后對done的執行,回調到業務類)
Manger類的聲明與實現
// 命令管理者以單例方式呈現
+ (instancetype)sharedInstance
{
static CommandManager *instance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[super allocWithZone:NULL] init];
});
return instance;
}
// 【必不可少】
+ (id)allocWithZone:(struct _NSZone *)zone{
return [self sharedInstance];
}
// 【必不可少】
- (id)copyWithZone:(nullable NSZone *)zone{
return self;
}
// 初始化方法
- (id)init
{
self = [super init];
if (self) {
// 初始化命令容器
_arrayCommands = [NSMutableArray array];
}
return self;
}
+ (void)executeCommand:(Command *)cmd completion:(CommandCompletionCallBack)completion
{
if (cmd) {
// 如果命令正在執行不做處理,否則添加并執行命令
if (![self _isExecutingCommand:cmd]) {
// 添加到命令容器當中
[[[self sharedInstance] arrayCommands] addObject:cmd];
// 設置命令執行完成的回調
cmd.completion = completion;
//執行命令
[cmd execute];
}
}
}
// 取消命令
+ (void)cancelCommand:(Command *)cmd
{
if (cmd) {
// 從命令容器當中移除
[[[self sharedInstance] arrayCommands] removeObject:cmd];
// 取消命令執行
[cmd cancel];
}
}
// 判斷當前命令是否正在執行
+ (BOOL)_isExecutingCommand:(Command *)cmd
{
if (cmd) {
NSArray *cmds = [[self sharedInstance] arrayCommands];
for (Command *aCmd in cmds) {
// 當前命令正在執行
if (cmd == aCmd) {
return YES;
}
}
}
return NO;
}
@end