iOS老司机可落地的中大型iOS项目中的设计模式优化Tips

6,735 阅读3分钟

我正在参加「掘金·启航计划」

1. 前言: 设计模式可以在大型项目中有哪些可落地的优化?

  • 本人目前负责一个中大型iOS项目,用PPRows跑一下项目根文件,目前代码量约28W。
  • 在这样一个大型项目中,我们组用了哪些方法对业务逻辑及代码架构进行解耦呢?
  • 在这种代码量级的项目中,有哪些接地气的,可落地的优化经验呢?
  • 在此抛砖引玉,欢迎大家一起相互探讨。

image.png

2. 落地: 采用责任链模式 应对产品大大提出的业务变更, 对业务代码进行解耦.

2.1 责任链模式导图

image.png

2.2 责任链模式解耦, 核心类文件构成

image.png

2.3 责任链模式解耦, 核心代码文件讲解

2.3.1 定义一个抽象的基类BusinessObject

  • BusinessObject.h文件
#import <Foundation/Foundation.h>

//NS_ASSUME_NONNULL_BEGIN


@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
  • BusinessObject.m文件
#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 {

    /**
     业务逻辑处理
     例如异步网络请求、异步本地照片查询等
     交给子类复写
     */

}


@end
  • 例如需要处理网络请求的业务A BusinessA
  • 业务A的BusinessObject.h文件
#import "BusinessObject.h"

NS_ASSUME_NONNULL_BEGIN

@interface BusinessA : BusinessObject

@end

NS_ASSUME_NONNULL_END
  • 业务A的BusinessObject.m文件
#import "BusinessA.h"

@implementation BusinessA

- (void)handleBusiness:(CompletionBlock)completion {
    NSLog(@"处理业务A");

    // 业务顺序: A -> B -> C
//    completion(NO);

    // 业务顺序: C -> B -> A
    completion(YES);
}

@end
  • 业务B的BusinessObjectB.h文件
#import "BusinessObject.h"

NS_ASSUME_NONNULL_BEGIN

@interface BusinessB : BusinessObject

@end

NS_ASSUME_NONNULL_END
  • 业务B的BusinessObjectB.m文件
#import "BusinessB.h"

@implementation BusinessB

- (void)handleBusiness:(CompletionBlock)completion {

    NSLog(@"处理业务B");

    // 业务顺序: A -> B -> C
//    completion(NO);

    // 业务顺序: C -> B -> A
    completion(NO);
}

@end
  • 业务C的BusinessObjectC.h文件
#import "BusinessObject.h"

NS_ASSUME_NONNULL_BEGIN

@interface BusinessC : BusinessObject

@end

NS_ASSUME_NONNULL_END
  • 业务C的BusinessObjectC.m文件
#import "BusinessC.h"


@implementation BusinessC

- (void)handleBusiness:(CompletionBlock)completion {

    NSLog(@"处理业务C");

    // 业务顺序: A -> B -> C
//    completion(YES);

    // 业务顺序: C -> B -> A
    completion(NO);
}

@end

2.3.2 实际业务使用责任链模式方法

//
//  ViewController.m
//  appDesignPattern
//
//  Created by JackLee on 2022/9/21.
//

#import "ViewController.h"
#import "BusinessA.h"
#import "BusinessB.h"
#import "BusinessC.h"

#import "appDesignPattern-Swift.h"

@interface ViewController ()

@end


@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    [self testBusiness];
}

- (void)testBusiness {

    BusinessA *businessObjA = [BusinessA new];
    BusinessB *businessObjB = [BusinessB new];
    BusinessC *businessObjC = [BusinessC new];
    // 业务顺序: A -> B -> C
//    businessObjA.nextBusiness = businessObjB;
//    businessObjB.nextBusiness = businessObjC;

    // 业务顺序: C -> B -> A
    businessObjC.nextBusiness = businessObjB;
    businessObjB.nextBusiness = businessObjA;


    // 响应者的处理方法, 责任链入口方法
    /*
     1. 当前业务处理掉了, 上抛结果
     2. 当前业务没处理掉, 沿着责任链, 指派给下一个业务处理, 如果没有业务处理, 继续上抛
     3. 对当前业务进行处理
     handler:
     handled: 业务处理结果
     */

    // 业务顺序: A -> B -> C
//    [businessObjA handle:^(BusinessObject *handler, BOOL handled) {
//
//
//    }];

    // 业务顺序: C -> B -> A
    [businessObjC handle:^(BusinessObject *handler, BOOL handled) {
        // handler: <BusinessA: 0x6000003da650>
        // handled: YES
    }];    

}

发文不易, 喜欢点赞的人更有好运气👍 :), 定期更新+关注不迷路~

ps:欢迎加入笔者18年建立的研究iOS审核及前沿技术的三千人扣群:662339934,坑位有限,备注“掘金网友”可被群管通过~