iOS老司機可落地的中大型iOS項目中的設計模式優化Tips

語言: CN / TW / HK

我正在參加「掘金·啟航計劃」

1. 前言: 設計模式可以在大型項目中有哪些可落地的優化?

  • 本人目前負責一箇中大型iOS項目,用PPRows跑一下項目根文件,目前代碼量約28W。
  • 在這樣一個大型項目中,我們組用了哪些方法對業務邏輯及代碼架構進行解耦呢?
  • 在這種代碼量級的項目中,有哪些接地氣的,可落地的優化經驗呢?
  • 在此拋磚引玉,歡迎大家一起相互探討。

image.png

2. 落地: 採用責任鏈模式 應對產品大大提出的業務變更, 對業務代碼進行解耦.

2.1 責任鏈模式導圖

image.png

2.2 責任鏈模式解耦, 核心類文件構成

image.png

2.3 責任鏈模式解耦, 核心代碼文件講解

2.3.1 定義一個抽象的基類BusinessObject

  • BusinessObject.h文件 ```

import

//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 )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:         // handled: YES     }];    

} ```

發文不易, 喜歡點讚的人更有好運氣👍 :), 定期更新+關注不迷路~

ps:歡迎加入筆者18年建立的研究iOS審核及前沿技術的三千人扣羣:662339934,坑位有限,備註“掘金網友”可被羣管通過~