好用的Middleware實現

王衛 mathew發表於2018-11-02

koaMiddleware--經典的洋蔥造型,在執行一個操作之前會先一層層的執行配置好的中介軟體,操作執行結束後再一層層的回溯。


在日常的iOS開發中,我們總是會遇這樣的一些場景:1.前往某個頁面,但是之前需要做多種的校驗;2. 執行某個操作,但是需要先呼叫不同的方法去準備一些資料等等。無論是這些校驗或者資料的準備如果都放在目標方法或者模組內都不是很合適,因為這些和目標的業務無關而且很有可能變化,比如去掉或增加一種校驗。這樣我們就需要使用Middleware來實現這種自由的組合場景。

設計思想

Middleware的一個主要思想就是需要一個Compose來儲存所有的Middleware,每一個Middleware會有一個**- (void)invoke:(id)context next:(NoneParamBlock)next方法,當Middleware開始執行的時候會呼叫這個方法,這個方法接受外面傳進來的公共引數和一個next()回撥用來移交執行權到下一個Middleware**

原始碼

github.com/MathewWang/…

Demo

先建立三個Middleware的filter子類


#import <Cocoa/Cocoa.h>
#import "ORMiddleWare.h"

@interface FirstFilter : ORMiddleWare

@end

#import "FirstFilter.h"

@implementation FirstFilter

- (void)invoke:(id)context next:(NoneParamBlock)next{
    NSLog(@"first filter doing work with context: %@", context);
    //執行權移交
    next();
    NSLog(@"first filter doing cleanup with context: %@", context);
}
複製程式碼
#import <Cocoa/Cocoa.h>
#import "ORMiddleWare.h"

@interface SecondFilter : ORMiddleWare

@end

#import "SecondFilter.h"

@implementation SecondFilter

- (void)invoke:(id)context next:(NoneParamBlock)next{
    NSLog(@"second filter doing work with context: %@", context);
    //執行權移交
    next();
    NSLog(@"second filter doing cleanup with context: %@", context);
}

@end

複製程式碼
#import <Cocoa/Cocoa.h>
#import "ORMiddleWare.h"

@interface ThirdFilter : ORMiddleWare

@end

#import "ThirdFilter.h"

@implementation ThirdFilter

- (void)invoke:(id)context next:(NoneParamBlock)next{
    NSLog(@"third filter doing work with context: %@", context);
    //執行權移交
    next();
    NSLog(@"third filter doing cleanup with context: %@", context);
}

@end
複製程式碼

最後將三個中介軟體組合,並執行業務程式碼

#import <Foundation/Foundation.h>
#import "ORCompose.h"
#import "FirstFilter.h"
#import "SecondFilter.h"
#import "ThirdFilter.h"


int main(int argc, const char * argv[]) {
    @autoreleasepool {
        [ORCompose compose:@[[FirstFilter new],
                             [SecondFilter new],
                             [ThirdFilter new]]]
        .run(@"context", ^{
            NSLog(@"doing business");
        });
    }
    return 0;
}

//結果
//first filter doing work with context: context
//second filter doing work with context: context
//third filter doing work with context: context
//doing business
//third filter doing cleanup with context: context
//second filter doing cleanup with context: context
//first filter doing cleanup with context: context
複製程式碼

結束,簡單好用。

相關文章