美文网首页
iOS 三种组件化方案

iOS 三种组件化方案

作者: 骨古 | 来源:发表于2017-11-28 14:52 被阅读32次

    趁着这段项目空闲期,把项目中用到的组件化方案记录一下,免得遗忘。
    简介
    组件化是为了各个模块不直接调用,降低耦合度,都是通过中间件来实现的,草图如下

    Snip20171128_4.png
    三种方案如下
    1.蘑菇街URL路由方案
    2.Target-Action方案
    3.procotol-class方案
    

    蘑菇街URL路由方案

    URL路由方案参考的是蘑菇街MGJRouter方案
    蘑菇街 App 的组件化之路

    Target-Action方案

    这个方案是根据casa大神的CTMediator的组件修改的,稍微修改下调用方法,和当前项目跟切合

    - (id)performTargetName:(NSString *)targetName actionName:(NSString *)actionName param:(NSDictionary *)dicParam;
    

    可以在每个模块对中间件加一个category,这样通过调用category方法,来降低耦合度,这是category的实现方法

    static NSString *const kBookTarget = @"BookTarget";
    static NSString *const kBookAction = @"bookVCWithParam";
    
    @implementation SYMediator (BookVC)
    - (UIViewController *)bookViewControllerWithDicParam:(NSDictionary *)dicParm
    {
        UIViewController *vc = [self performTargetName:kBookTarget actionName:kBookAction param:dicParm];
        if ([vc isKindOfClass:[UIViewController class]]) {
            return vc;
        } else {
            return [[UIViewController alloc] init];
        }
    }
    

    当然也不可以增加category,也可以实现。

        NSDictionary *dicParm = @{@"bookName" : @"降龙十八掌",@"bookid" : @"sy0001"};
        //第一种方式(有category)
        UIViewController *bookVC = [[SYMediator shareInstance] bookViewControllerWithDicParam:dicParm];
        [self.navigationController pushViewController:bookVC animated:YES];
        
        //第二种方式 其实不对SYMediator 增加Category也是可以实现的,就是代码比较恶心而已 下面就是例子
    //    UIViewController *bookVC2 = [[SYMediator shareInstance] performTargetName:@"BookTarget" actionName:@"bookVCWithParam" param:dicParm];
    //    [self.navigationController pushViewController:bookVC2 animated:YES];
    

    bang大神的总结 组件通过中间件通信,中间件通过 runtime 接口解耦,通过 target-action 简化写法,通过 category 感官上分离组件接口代码

    procotol-class方案

    这种方案是蘑菇街为了补全本地调用的功能,为组件多加了另一种方案,就是通过 protocol-class 注册表的方式
    还是通过一个中间件来实现的

    - (void)registerProtocol:(Protocol *)protocl forClass:(id)provide;
    
    - (id)classForProtol:(Protocol *)protocol;
    

    具体实现就是把procotolclass做一个映射,同时在内存中保存一张映射表,使用的时候,就通过protocol找到对应的class来获取需要的服务

    - (void)registerProtocol:(Protocol *)protocl forClass:(id)provide
    {
        if (!protocl || !provide) {
            return;
        }
        
        NSString *protocolName = NSStringFromProtocol(protocl);
        [self.protocolCache setObject:provide forKey:protocolName];
        
    }
    
    - (id)classForProtol:(Protocol *)protocol
    {
        if (!protocol) {
            return nil;
        }
        return self.protocolCache[NSStringFromProtocol(protocol)];
    }
    

    在每个模块内定义一个公共Procotol文件,定义对外的接口

    //ProtocolBookProtocol.h
    @protocol ProtocolBookProtocol <NSObject>
    - (UIViewController *)bookVCWithParam:(NSDictionary *)dicParm;
    @end
    

    最后在模块里实现这些接口

        // procotol-class 方案 有点绕 这个方案跟刚才两个最大的不同就是,它不是直接通过 Mediator 调用组件方法,而是通过 Mediator 拿到组件对象,再自行去调用组件方法
        NSDictionary *dicParm = @{@"bookName" : @"降龙十八掌",@"bookid" : @"sy0001"};
    
        //1.拿到组件对象
        id<ProtocolBookProtocol> protocolBookManager = [[ProcotolManagerTool shareInstance] classForProtol:@protocol(ProtocolBookProtocol)];
        //2.通过组件对象 再传值
        UIViewController *bookVC = [protocolBookManager bookVCWithParam:dicParm];
        [self.navigationController pushViewController:bookVC animated:YES];
    

    demo
    参考链接:
    iOS 组件化方案探索
    蘑菇街 App 的组件化之路
    iOS应用架构谈 组件化方案

    相关文章

      网友评论

          本文标题:iOS 三种组件化方案

          本文链接:https://www.haomeiwen.com/subject/yensbxtx.html