美文网首页
iOS设计模式

iOS设计模式

作者: Li_Po | 来源:发表于2020-10-19 12:34 被阅读0次
    • 五种设计模式:责任链模式、桥接模式、适配器模式、单例模式、命令模式。
    • 六大设计原则:单一职责、开闭原则、 接口隔离原则、依赖倒置原则、里式替换原则、迪米特法责。

    六大设计原则

    • 单一职责:一个类只负责一件事,如:UIview负责事件传递及事件响应、calayer负责动画及视图显示。
    • 开闭原则:对修改关闭,对扩展开放。
    • 接口隔离原则:使用多个专门的协议,而不是一个庞大臃* 肿的协议,如tableview的delegate和DataSource
    • 依赖倒置原则:抽象不应该依赖具体实现,具体实现可以依赖于抽象,如上层多个调用可使用同一个接口,接口内部可以有不同的实现方案
    • 里式替换原则:父类可以被子类无缝替换,且原有功能不受影响,如KVO
    • 迪米特法责:一个对象应当对其他对象有尽可能少的了解,高内聚、低耦合

    设计模式:

    • 责任链:如:业务A->业务B->业务C 当需求变更为 业务C->业务B->业务A 可以使用责任链模式解决

         #import <Foundation/Foundation.h>
        @class BusinessObject;
        typedef void(^CompletionBlock)(BOOL handled);
        typedef void(^ResultBlock)(BusinessObject *handler, BOOL handled);
      
        @interface BusinessObject : NSObject
        // 下一个响应者(响应链构成的关键)
        @property (nonatomic, strong) BusinessObject *nextBusiness;
        // 响应者的处理方法
        - (void)handle:(ResultBlock)result;
        // 各个业务在该方法当中做实际业务处理
        - (void)handleBusiness:(CompletionBlock)completion;
        @end
      
      
        #import "BusinessObject.h"
        @implementation BusinessObject
      
        // 责任链入口方法
        - (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
        {
            /*
             业务逻辑处理
             如网络请求、本地照片查询等
              处理完成后回调CompletionBlock
             */
        }
        @end
      
    • 桥接:

    依赖倒置


    image.png
    image.png
      代码示例
        #import <Foundation/Foundation.h>
        @interface BridgeDemo : NSObject
        - (void)fetch;
        @end
    
        #import "BridgeDemo.h"
        #import "BaseObjectA.h"
        #import "BaseObjectB.h"
        #import "ObjectA1.h"
        #import "ObjectA2.h"
        #import "ObjectB1.h"
        #import "ObjectB2.h"
        @interface BridgeDemo()
        @property (nonatomic, strong) BaseObjectA *objA;
        @end
    
        @implementation BridgeDemo
    
        /*
         根据实际业务判断使用那套具体数据
         A1 --> B1、B2、B3         3种
         A2 --> B1、B2、B3         3种
         A3 --> B1、B2、B3         3种
         */
        - (void)fetch
        {
            // 创建一个具体的ClassA
            _objA = [[ObjectA1 alloc] init];
            
            // 创建一个具体的ClassB
            BaseObjectB *b1 = [[ObjectB1 alloc] init];
            // 将一个具体的ClassB1 指定给抽象的ClassB
            _objA.objB = b1;
            
            // 获取数据
            [_objA handle];
        }
        @end
    
        #import <Foundation/Foundation.h>
        #import "BaseObjectB.h"
        @interface BaseObjectA : NSObject
        // 桥接模式的核心实现
        @property (nonatomic, strong) BaseObjectB *objB;
        // 获取数据
        - (void)handle;
        @end
    
        #import "BaseObjectA.h"
        @implementation BaseObjectA
         /*
            A1 --> B1、B2、B3         3种
            A2 --> B1、B2、B3         3种
            A3 --> B1、B2、B3         3种
          */
        - (void)handle
        {
            // override to subclass
            [self.objB fetchData];
        }
        @end
    
        #import "ObjectA1.h"
        @implementation ObjectA1
        - (void)handle
        {
            // before 业务逻辑操作
            [super handle];
            // after 业务逻辑操作
        }
        @end
    
        #import "ObjectA2.h"
        @implementation ObjectA2
        - (void)handle
        {
            // before 业务逻辑操作
            [super handle];
            // after 业务逻辑操作
        }
        @end
    
        #import <Foundation/Foundation.h>
        @interface BaseObjectB : NSObject
        - (void)fetchData;
        @end
    
        #import "BaseObjectB.h"
        @implementation BaseObjectB
        - (void)fetchData
        {
            // override to subclass
            //抽象类,具体实现放到子类中
        }
        @end
    
        #import "ObjectB1.h"
        @implementation ObjectB1
        - (void)fetchData{
            // 具体的逻辑处理
        }
        @end
    
        #import "ObjectB2.h"
        @implementation ObjectB2
        - (void)fetchData{
            // 具体的逻辑处理
        }
        @end
    
    • 适配器:
      一个现有类需要适应变化的问题
      对象适配器
      类适配器
    image.png

    -(void)request{//新类中的方法
    //适配逻辑,添加额外的方法
    [被适配对象 某方法];//可能是多个方法
    //适配逻辑,添加额外的方法
    }

    • 单例:

      + (id)sharedInstance
        {
            // 静态局部变量
            static ClassA *instance = nil;
            
            // 通过dispatch_once方式 确保instance在多线程环境下只被创建一次
            static dispatch_once_t onceToken;
            dispatch_once(&onceToken, ^{
                // 创建实例
                //要使用super(使用self会引起循环调用)
                instance = [[super allocWithZone:NULL] init];
            });
            return instance;
        }
      
        // 重写方法【必不可少】
        + (id)allocWithZone:(struct _NSZone *)zone{
            return [self sharedInstance];
        }
      
        // 重写方法【必不可少】
        - (id)copyWithZone:(nullable NSZone *)zone{
            return self;
        }
      
    • 命令:
      行为参数化
      降低代码重合度

        //命令模式代码示例Command命令、CommandManager命令管理者
      
        #import <Foundation/Foundation.h>
      
        @class Command;
        typedef void(^CommandCompletionCallBack)(Command* cmd);
      
        @interface Command : NSObject
        @property (nonatomic, copy) CommandCompletionCallBack completion;
        - (void)execute;//执行
        - (void)cancel;//取消
        - (void)done;//完成
        @end
      
        #import "Command.h"
        #import "CommandManager.h"
        @implementation Command
      
        - (void)execute{
            //写要做的事
            [self done];
        }
        - (void)cancel{
            self.completion = nil;//取消回调block
        }
        - (void)done
        {
            dispatch_async(dispatch_get_main_queue(), ^{
                //block回调
                if (_completion) {
                    _completion(self);
                }
                //释放
                self.completion = nil;
                //在任务管理者里面移除本次命令
                [[CommandManager sharedInstance].arrayCommands removeObject:self];
            });
        }
        @end
      
        #import <Foundation/Foundation.h>
        #import "Command.h"
        @interface CommandManager : NSObject
        // 命令管理容器
        @property (nonatomic, strong) NSMutableArray <Command*> *arrayCommands;
      
        // 命令管理者以单例方式呈现
        + (instancetype)sharedInstance;
        // 执行命令
        + (void)executeCommand:(Command *)cmd completion:(CommandCompletionCallBack)completion;
        // 取消命令
        + (void)cancelCommand:(Command *)cmd;
        @end
      
        #import "CommandManager.h"
        @implementation CommandManager
      
        // 命令管理者以单例方式呈现
        + (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

    相关文章

      网友评论

          本文标题:iOS设计模式

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