设计模式
设计模式内容如下:
- 责任链模式
- 桥接模式
- 命令模式
- 适配器模式
- 单例模式
- 等等
设计原则
作为一个开发者,有一个学习的氛围跟一个交流圈子特别重要,这是一个我的iOS交流群:642363427不管你是小白还是大牛欢迎入驻 ,分享BAT,阿里面试题、面试经验,讨论技术, 大家一起交流学习成长!
推荐阅读
iOS开发——最新 BAT面试题合集(持续更新中)
- 单一职责原则 - 开闭原则 - 接口隔离原则 - 依赖倒置原则 - 里氏替换原则 - 迪米特法则
- 单一职责原则
一个类只负责一件事(UIView与CALayer)
- 开闭原则
对修改关闭,对扩展开放 定义一个类,考虑后续的扩展及灵活性
- 接口隔离原则
使用多个专门的协议,而不是一个臃肿的协议,比较表的协议
- 依赖倒置原则
抽象不应该依赖于具体实现,具体实现可以依赖于抽象
- 里氏替换原则
父类可以被子类无缝替换,且原有功能不受任何影响,比如KVO
- 迪米特法则
- 一个对象应当对其他对象有尽可能少的了解 - 高内聚,低耦合
1.责任链模式
- 原业务逻辑是 先调用业务A ,再调用业务B,再调用业务C - 修改业务逻辑,先调用业务C,再调用业务B,再调用业务A 如何进行需求变更的修改?
- (void)handle:(ResultBlock)result { CompletionBlock completion = ^(BOOL handled){ // 当前业务处理 if (handled) { result(self, handled); } else{ // 沿着责任链,指派给下一个业务处理 if (self.nextBusiness) { [self.nextBusiness handle:result]; } else{ // 没有业务处理 result(nil, NO); } } }; // 当前业务进行处理 [self handleBusiness:completion]; } - (void)handleBusiness:(CompletionBlock)completion { // 业务逻辑处理 }
2.桥接模式
三条网络数据并存在列表中
案例: BridgeClass类: #import <Foundation/Foundation.h> @interface BridgeClass : NSObject - (void)fetch; @end #import "BridgeClass.h" #import "BaseA.h" #import "BaseB.h" #import "A1.h" #import "A2.h" #import "A3.h" #import "B1.h" #import "B2.h" #import "B3.h" @interface BridgeClass() @property (nonatomic, strong) BaseA *baseA; @end @implementation BridgeClass - (void)fetch { // 创建一个具体的ClassA _baseA = [[A1 alloc] init]; // 创建一个具体的ClassB BaseB *b1 = [[B1 alloc] init]; // 将一个具体的B1 指定给抽象的ClassB _baseA.baseB = b1; // 获取数据 [_baseA handle]; } @end
BaseA类 #import <Foundation/Foundation.h> #import "BaseB.h" @interface BaseA : NSObject // 桥接模式的核心实现 @property (nonatomic, strong) BaseB *baseB; // 获取数据 - (void)handle; @end #import "BaseA.h" @implementation BaseA - (void)handle { // override to subclass [self.baseB fetchData]; } @end
A1类: #import "BaseA.h" @interface A1 : BaseA @end #import "A1.h" @implementation A1 - (void)handle { // before 业务逻辑操作 [super handle]; // after 业务逻辑操作 } @end
A2类: #import "BaseA.h" @interface A2 : BaseA @end #import "A2.h" @implementation A2 - (void)handle { // before 业务逻辑操作 [super handle]; // after 业务逻辑操作 } @end
A3类: #import "BaseA.h" @interface A3 : BaseA @end #import "A3.h" @implementation A3 - (void)handle { // before 业务逻辑操作 [super handle]; // after 业务逻辑操作 } @end
BaseB类 #import <Foundation/Foundation.h> @interface BaseB : NSObject - (void)fetchData; @end #import "BaseB.h" @implementation BaseB - (void)fetchData { // override to subclass } @end
B1类: #import "BaseB.h" @interface B1 : BaseB @end #import "B1.h" @implementation B1 - (void)fetchData{ // 具体的逻辑处理 } @end
B2类: #import "BaseB.h" @interface B2 : BaseB @end #import "B2.h" @implementation B2 - (void)fetchData{ // 具体的逻辑处理 } @end
B3类: #import "BaseB.h" @interface B3 : BaseB @end #import "B3.h" @implementation B3 - (void)fetchData{ // 具体的逻辑处理 } @end
3.适配器模式
一个类需要适应变化,如何解决?
- 对象适配器
适配对象->成员变量->被适配对象
案例: 被适配对象(A类): #import <Foundation/Foundation.h> @interface A : NSObject - (void)operation; @end #import "A.h" @implementation A - (void)operation { // 原有的具体业务逻辑 } @end
适配对象(B类): #import "A.h" // 适配对象 @interface B : NSObject // 被适配对象 @property (nonatomic, strong) A *a; // 对原有方法包装 - (void)request; @end #import "B.h" @implementation B - (void)request { // 额外处理 [self.a operation]; // 额外处理 } @end
4.单例模式
案例: 单例类A: #import <Foundation/Foundation.h> @interface A : NSObject + (id)sharedInstance; @end #import "A.h" @implementation A + (id)sharedInstance { // 静态局部变量 static A *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; } @end
5.命令模式
- 行为参数化 - 降低代码重合度
案例: Comd类: #import <Foundation/Foundation.h> @class Comd; typedef void(^ComdCompletionCallBack)(Comd* cmd); @interface Comd : NSObject @property (nonatomic, copy) ComdCompletionCallBack completion; - (void)execute; - (void)cancel; - (void)done; @end #import "Comd.h" #import "Co***nager.h" @implementation Comd - (void)execute{ //override to subclass; [self done]; } - (void)cancel{ self.completion = nil; } - (void)done { dispatch_async(dispatch_get_main_queue(), ^{ if (_completion) { _completion(self); } //释放 self.completion = nil; [[Co***nager sharedInstance].arrayComds removeObject:self]; }); } @end
Co***nager类: #import <Foundation/Foundation.h> #import "Comd.h" @interface Co***nager : NSObject // 命令管理容器 @property (nonatomic, strong) NSMutableArray <Comd*> *arrayComds; // 命令管理者以单例方式呈现 + (instancetype)sharedInstance; // 执行 + (void)executeCommand:(Comd *)cmd completion:(ComdCompletionCallBack)completion; // 取消 + (void)cancelCommand:(Comd *)cmd; @end #import "Co***nager.h" @implementation Co***nager // 命令管理者以单例方式呈现 + (instancetype)sharedInstance { static Co***nager *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) { // 初始化命令容器 _arrayComds = [NSMutableArray array]; } return self; } + (void)executeCommand:(Comd *)cmd completion:(ComdCompletionCallBack)completion { if (cmd) { // 如果命令正在执行不做处理,否则添加并执行命令 if (![self _isExecutingCommand:cmd]) { // 添加到命令容器当中 [[[self sharedInstance] arrayComds] addObject:cmd]; // 设置命令执行完成的回调 cmd.completion = completion; //执行命令 [cmd execute]; } } } // 取消命令 + (void)cancelCommand:(Comd *)cmd { if (cmd) { // 从命令容器当中移除 [[[self sharedInstance] arrayComds] removeObject:cmd]; // 取消命令执行 [cmd cancel]; } } // 判断当前命令是否正在执行 + (BOOL)_isExecutingCommand:(Comd *)cmd { if (cmd) { NSArray *cmds = [[self sharedInstance] arrayComds]; for (Comd *aCmd in cmds) { // 当前命令正在执行 if (cmd == aCmd) { return YES; } } } return NO; } @end
面试题:
- 单例实现
- 设计原则
- 描绘桥接模式
- UI事件传递机制?运用到什么设计模式?