好用的Middleware实现

514 阅读2分钟

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

结束,简单好用。