美文网首页
蘑菇街组件化笔记

蘑菇街组件化笔记

作者: Crazy2015 | 来源:发表于2018-06-27 20:57 被阅读59次
    路由的基础知识

    iOS 系统里面支持的URL Scheme方式,我们可以看出,对于一个资源的访问,苹果也是用URI的方式来访问的。
    统一资源标识符(英语:Uniform Resource Identifier,或URI)是一个用于标识某一互联网资源名称的字符串。 该种标识允许用户对网络中(一般指万维网)的资源通过特定的协议进行交互操作。URI的最常见的形式是统一资源定位符(URL)。

    1488337532106663.png

    路由开源的库:
    http://www.cocoachina.com/ios/20170301/18811.html (参考如下的文章)

    组件之间的通信

    URL路由的方式

    注册:MGJRouter

    各个组件初始化时向 Mediator 注册对外提供的接口,Mediator 通过保存在内存的表去知道有哪些模块哪些接口,接口的形式是 URL->block。

    这种方案思路就是:Mediator 不能直接去调用组件的方法,因为这样会产生依赖,那我就要通过其他方法去调用,也就是通过 字符串->方法 的映射去调用。runtime 接口的 className + selectorName -> IMP 是一种,注册表的 key -> block 是一种,而前一种是 OC 自带的特性,后一种需要内存维持一份注册表。

    从数据结构来看

    @interface MGJRouter ()
    /**
     *  保存了所有已注册的 URL
     *  结构类似 @{@"beauty": @{@":id": {@"_", [block copy]}}}
     */
    @property (nonatomic) NSMutableDictionary *routes;
    @end
    
    /**
     *  打开此 URL,带上附加信息,同时当操作完成时,执行额外的代码
     *
     *  @param URL        带 Scheme 的 URL,如 mgj://beauty/4
     *  @param userInfo 附加参数
     *  @param completion URL 处理完成后的 callback,完成的判定跟具体的业务相关
     */
    + (void)openURL:(NSString *)URL withUserInfo:(NSDictionary *)userInfo completion:(void (^)(id result))completion;
    
    1488345388154476.png
    蘑菇街为了区分开页面间调用和组件间调用,于是想出了一种新的方法。用Protocol的方法来进行组件间的调用。

    每个组件之间都有一个 Entry,这个 Entry,主要做了三件事:

    • 注册这个组件关心的 URL

    • 注册这个组件能够被调用的方法/属性

    • 在 App 生命周期的不同阶段做不同的响应

    页面间的openURL调用就是如下的样

    1488345427296974.png

    每个组件间都会向MGJRouter注册,组件间相互调用或者是其他的App都可以通过openURL:方法打开一个界面或者调用一个组件。

    在组件间的调用,蘑菇街采用了Protocol的方式。

    1488345587646575.png

    [ModuleManager registerClass:ClassA forProtocol:ProtocolA] 的结果就是在 MM 内部维护的 dict 里新加了一个映射关系。

    [ModuleManager classForProtocol:ProtocolA] 的返回结果就是之前在 MM 内部 dict 里 protocol 对应的 class,使用方不需要关心这个 class 是个什么东东,反正实现了 ProtocolA 协议,拿来用就行。

    这里需要有一个公共的地方来容纳这些 public protocl,也就是图中的 PublicProtocl.h。

    我猜测,大概实现可能是下面的样子:

    [图片上传中...(1488350374526176.png-ba68e1-1530103740148-0)]

    然后这个是一个单例,在里面注册各个协议:


    [图片上传中...(1488350511106764.png-9f1356-1530103814895-0)]

    在ModuleProtocolManager中用一个字典保存每个注册的protocol。现在再来猜猜ModuleEntry的实现


    1488350511106764.png

    然后每个模块内都有一个和暴露到外面的协议相连接的“接头”。


    1488346149928315 (1).png

    在它的实现中,需要引入3个外部文件,一个是ModuleProtocolManager,一个是DetailModuleEntryProtocol,最后一个是所在模块需要跳转或者调用的组件或者页面。

    1488346189157631.png

    至此基于Protocol的方案就完成了。如果需要调用某个组件或者跳转某个页面,只要先从ModuleProtocolManager的字典里面根据对应的ModuleEntryProtocol找到对应的DetailModuleEntry,找到了DetailModuleEntry就是找到了组件或者页面的“入口”了。再把参数传进去即可。

    1488346213448859.png

    这样就可以调用到组件或者界面了。

    如果组件之间有相同的接口,那么还可以进一步的把这些接口都抽离出来。这些抽离出来的接口变成“元接口”,它们是可以足够支撑起整个组件一层的。

    相关文章

      网友评论

          本文标题:蘑菇街组件化笔记

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