iOS面试之设计模式模块

设计模式

设计模式内容如下:

  • 责任链模式
  • 桥接模式
  • 命令模式
  • 适配器模式
  • 单例模式
  • 等等
iOS面试之设计模式模块_第1张图片
设计模式.png

设计原则

- 单一职责原则
- 开闭原则
- 接口隔离原则
- 依赖倒置原则
- 里氏替换原则
- 迪米特法则
  • 单一职责原则
一个类只负责一件事(UIView与CALayer)
  • 开闭原则
对修改关闭,对扩展开放
定义一个类,考虑后续的扩展及灵活性
  • 接口隔离原则
使用多个专门的协议,而不是一个臃肿的协议,比较表的协议
  • 依赖倒置原则
抽象不应该依赖于具体实现,具体实现可以依赖于抽象
  • 里氏替换原则
父类可以被子类无缝替换,且原有功能不受任何影响,比如KVO
  • 迪米特法则
- 一个对象应当对其他对象有尽可能少的了解
- 高内聚,低耦合

1.责任链模式

iOS面试之设计模式模块_第2张图片
业务逻辑变更.png
- 原业务逻辑是 先调用业务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.桥接模式

iOS面试之设计模式模块_第3张图片
业务解耦.png
三条网络数据并存在列表中
案例:
BridgeClass类:

#import 
@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 
#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 
@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 
@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 
@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 

@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 "ComdManager.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;
        
        [[ComdManager sharedInstance].arrayComds removeObject:self];
    });
}
@end
ComdManager类:

#import 
#import "Comd.h"
@interface ComdManager : NSObject
// 命令管理容器
@property (nonatomic, strong) NSMutableArray  *arrayComds;
// 命令管理者以单例方式呈现
+ (instancetype)sharedInstance;
// 执行
+ (void)executeCommand:(Comd *)cmd completion:(ComdCompletionCallBack)completion;
// 取消
+ (void)cancelCommand:(Comd *)cmd;
@end

#import "ComdManager.h"

@implementation ComdManager

// 命令管理者以单例方式呈现
+ (instancetype)sharedInstance
{
    static ComdManager *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事件传递机制?运用到什么设计模式?

QQ交流群: 796142709

你可能感兴趣的:(iOS面试之设计模式模块)