iOS设计模式

  • 五种设计模式:责任链模式、桥接模式、适配器模式、单例模式、命令模式。
  • 六大设计原则:单一职责、开闭原则、 接口隔离原则、依赖倒置原则、里式替换原则、迪米特法责。

六大设计原则

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

设计模式:

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

       #import 
      @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 
    @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 
    #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 
    @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 
    
      @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 
      #import "Command.h"
      @interface CommandManager : NSObject
      // 命令管理容器
      @property (nonatomic, strong) NSMutableArray  *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设计模式)