美文网首页
组件化方案 阅读笔记

组件化方案 阅读笔记

作者: 莫小哈 | 来源:发表于2017-06-15 17:19 被阅读5次

    组件

    从功能业务角度上看不能在查分,适可替换,可复用的.

    模块

    有多个组件组成,他可以实现一个独立的功能,一个或多个业务.

    例如大众点评的美食功能是一个业务,也可以叫做"美食模块".

    模块化开发 中介者
    //Mediator.m 中间件代码
    @implementation Mediator
    + (UIViewController *)OpenViewController1:(NSString *)viewId {
     Class cls = NSClassFromString(@"UIViewController1");
     return [cls performSelector:NSSelectorFromString(@"viewController1:") withObject:@{@"viewId": viewId}];
    }
    + (UIViewController *) OpenViewController2:(NSString *) viewId type:(NSInteger)type {
     Class cls = NSClassFromString(@"UIViewController2");
     return [cls performSelector:NSSelectorFromString(@"viewController2:") withObject:@{@"viewId": viewId, @"type": @(type)}];
    }
    @end
    
    //调用者
    #import "Mediator.h"
    @implementation ViewController
    - (void)gotoViewController1 {
     UIViewController * vc = [Mediator OpenViewController1:@"id" ];
     [self.navigationController pushViewController: vc animated:YES];
    }
    
    - (void) gotoViewController2 {
     UIViewController * vc = [Mediator OpenViewController1:@"id" type:1 ];
     [self.navigationController pushViewController: vc animated:YES];
    }
    @end
    

    这样在调用里面就不用引用 UIViewController1和 UIViewController1 的头文件了 就不会产生相互依赖 只要在调用其他组件的时候引入 Mediator.h 就可以了.接下来就是优化这套写法,有两个优化点:
    1.Mediator 每一个方法里都要写 runtime 方法,格式是确定的,这是可以抽取出来的。
    2.每个组件对外方法都要在 Mediator 写一遍,组件一多 Mediator 类的长度是恐怖的。

    蘑菇街为了补全本地调用的功能,为组件多加了另一种方案,就是通过 protocol-class 注册表的方式。(感觉比上面的方案要复杂很多)
    首先有一个新的中间件:

    //ProtocolMediator.m 新中间件
    @implementation ProtocolMediator
    @property (nonatomic, storng) NSMutableDictionary *protocolCache
    //注册协议协议
    - (void)registerProtocol:(Protocol *)proto forClass:(Class)cls {
     NSMutableDictionary *protocolCache;
     [protocolCache setObject:cls forKey:NSStringFromProtocol(proto)];
    }
    
    - (Class)classForProtocol:(Protocol *)proto {
     return protocolCache[NSStringFromProtocol(proto)];
    }
    @end
    

    然后有一个公共Protocol文件,定义了每一个组件对外提供的接口:

    //ComponentProtocol.h
    @protocol BookDetailComponentProtocol <NSObject>
    - (UIViewController *)bookDetailController:(NSString *)bookId;
    - (UIImage *)coverImageWithBookId:(NSString *)bookId;
    @end
    
    @protocol ReviewComponentProtocol <NSObject>
    - (UIViewController *)ReviewController:(NSString *)bookId;
    @end
    

    再在模块里实现这些接口,并在初始化时调用 registerProtocol 注册。

    //BookDetailComponent 组件
    #import "ProtocolMediator.h"
    #import "ComponentProtocol.h"
    #import "WRBookDetailViewController.h"
    + (void)initComponent
    {
     [[ProtocolMediator sharedInstance] registerProtocol:@protocol(BookDetailComponentProtocol) forClass:[self class];
    }
    
    - (UIViewController *)bookDetailController:(NSString *)bookId {
     WRBookDetailViewController *detailVC = [[WRBookDetailViewController alloc] initWithBookId:param[@"bookId"]];
     return detailVC;
    }
    
    - (UIImage *)coverImageWithBookId:(NSString *)bookId {
     ….
    }
    

    最后调用者通过 protocol 从 ProtocolMediator 拿到提供这些方法的 Class,再进行调用:

    //WRReadingViewController.m 调用者
    //ReadingViewController.m
    #import "ProtocolMediator.h"
    #import "ComponentProtocol.h"
    + (void)gotoDetail:(NSString *)bookId {
     Class cls = [[ProtocolMediator sharedInstance] classForProtocol:BookDetailComponentProtocol];
     id bookDetailComponent = [[cls alloc] init];
     UIViewController *vc = [bookDetailComponent bookDetailController:bookId];
     [[UIApplication sharedApplication].keyWindow.rootViewController.navigationController pushViewController:vc animated:YES];
    }
    

    相关文章

      网友评论

          本文标题:组件化方案 阅读笔记

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