美文网首页
iOS面试之设计模式大全

iOS面试之设计模式大全

作者: 原来是泽镜啊 | 来源:发表于2020-09-03 14:56 被阅读0次

    设计模式

    设计模式内容如下:

    • 责任链模式
    • 桥接模式
    • 命令模式
    • 适配器模式
    • 单例模式
    • 等等

    设计原则

    作为一个开发者,有一个学习的氛围跟一个交流圈子特别重要,这是一个我的iOS交流群:413038000,不管你是大牛还是小白都欢迎入驻 ,分享BAT,阿里面试题、面试经验,讨论技术, 大家一起交流学习成长!

    推荐阅读

    iOS开发——最新 BAT面试题合集(持续更新中)

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

    1.责任链模式

    image
    - 原业务逻辑是 先调用业务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.桥接模式

    image
    三条网络数据并存在列表中
    
    
    案例:
    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 "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 <Foundation/Foundation.h>
    #import "Comd.h"
    @interface ComdManager : NSObject
    // 命令管理容器
    @property (nonatomic, strong) NSMutableArray <Comd*> *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事件传递机制?运用到什么设计模式?

    文章来源于网络,如有侵权,请联系小编删除。

    相关文章

      网友评论

          本文标题:iOS面试之设计模式大全

          本文链接:https://www.haomeiwen.com/subject/netosktx.html