iOS组件化实践方案-LDBusMediator炼就


3.1 组件化方案不彻底之处和JLRoute的缺陷

通过第二部分的讲述,我们的组件化工作差不多完成了80%,但是我们依然发现,组件化并不够彻底。

先来看服务调用方面,我们需要对外提供OpenServiceImpl的头文件,外部模块仍然保持着对业务组件的强依赖,OpenServiceImpl的不兼容变化必然导致所有调用部分的更改,我们期望的黑盒服务便无法实现。如果所有类别的服务接口都在OpenServiceImpl中实现,OpenServiceImpl中的代码会越来越多,难以维护和管理。 另外Protocol文件和OpenServiceImpl的头文件都需要对外披露,如果放到组件实现中,两个组件相互之间有调用,就会导致Podspec的相互循环依赖。

再看URL导航方面,在我们的项目中,我们在ViewController的类别中通过load方法注册URL-Block,这样能够解决JLRoute的中心化注册问题,但是JLRoute仍然存在其他一些缺陷。JLRoute去中心化的具体使用方式如下:

  • (void)load

{

@autoreleasepool {

[JLRoutes addRoute:@“/xxxx” handler:^BOOL(NSDictionary *parameters) {

UIViewController *baseViewController = parameters[kLDRouteViewControllerKey];

if (!baseViewController) {

baseViewController = [UIViewController topmostViewController];

}

if (!baseViewController) {

return YES;

}

XXXXViewController *viewController = [[XXXXViewController alloc] init];

if ([baseViewController isKindOfClass:[UINavigationController class]]) {

[(UINavigationController*)baseViewController pushViewController:viewController animated:YES];

}else if (baseViewController.navigationController) {

[baseViewController.navigationController pushViewController:viewController animated:YES];

} else {

UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:viewController];

[baseViewController presentViewController:navController animated:YES completion:NULL];

}

return YES;

}];

}

}

如上所用,JLRoute的缺陷如下:

  • url短链分布式注册时,导航代码的重复拷贝;

  • 无法通过URL返回一个controller实例;(TabController也就无法从独立业务组件中不引用Controller头文件获取Controller实例完成设置)

  • class的load方法完成注册,太多对启动时Main线程有影响;

  • 同一个url短链的导航方式单一固定,依赖注册

  • 单一业务组件中可导航URL分散,无法统一查看;

  • Debug阶段url传递参数错误、not found没有提示;

3.2 LDBusMediator总体方案

针对组件化不彻底的实际问题,结合之前手淘分享的总线架构以及蘑菇街的组件化分享博客,我们完成了一个通用的LDBusMediator中间件帮助我们彻底完成组件化。

LDBusMediator开源Git地址:

我们先来看总体的组件化方案:所有的业务组件通过Connector连接到总线中,Connector需要遵循Connector Protocol方可接入。Connector协议规定了URL导航接入和服务接入的协议,Connector通过Class的Load方法将自己的实例注册到中间件的Cache数组中,方便其他组件在调用时中间件可以通过服务发现的方式进行URL导航和服务调用。(具体见如下的图示)

@implementation Connector_A

#pragma mark - register connector

/**

  • 每个组件的实现必须自己通过load完成挂载;

  • load只需要在挂载connector的时候完成当前connecotor的初始化,挂载量、挂载消耗、挂载所耗内存都在可控范围内;

*/

+(void)load{

@autoreleasepool{

[LDBusMediator registerConnector:[self sharedConnector]];

}

}

@end

3.3 LDBusMediator-URL导航方案

URL导航的总线中间件方案很简单,只需要在Connector中实现URL导航接入的接口即可,如图所示:

LDBusMediator-URL导航.png

具体使用如下:

@protocol LDBusConnectorPrt

-(BOOL)canOpenURL:(nonnull NSURL *)URL;

  • (nullable UIViewController *)connectToOpenURL:(nonnull NSURL *)URL params:(nullable NSDictionary *)params;

@end

@implementation Connector_A

#pragma mark - LDBusConnectorPrt

/**

  • (1)当调用方需要通过判断URL是否可导航显示界面的时候,告诉调用方该组件实现是否可导航URL;可导航,返回YES,否则返回NO;

  • (2)这个方法跟connectToOpenURL:params配套实现;如果不实现,则调用方无法判断某个URL是否可导航;

*/

-(BOOL)canOpenURL:(nonnull NSURL *)URL{

if ([URL.host isEqualToString:@“ADetail”]) {

return YES;

}

return NO;

}

@end

/**

  • (1)通过connector向busMediator挂载可导航的URL,具体解析URL的host还是path,由connector自行决定;

  • (2)如果URL在本业务组件可导航,则从params获取参数,实例化对应的viewController进行返回;如果参数错误,则返回一个错误提示的[UIViewController paramsError]; 如果不需要中间件进行present展示,则返回一个[UIViewController notURLController],表示当前可处理;如果无法处理,返回nil,交由其他组件处理;

  • (3)需要在connector中对参数进行验证,不同的参数调用生成不同的ViewController实例;也可以通过参数决定是否自行展示,如果自行展示,则用户定义的展示方式无效;

  • (4)如果挂接的url较多,这里的代码比较长,可以将处理方法分发到当前connector的category中;

*/

  • (nullable UIViewController *)connectToOpenURL:(nonnull NSURL *)URL params:(nullable NSDictionary *)params{

//处理scheme://ADetail的方式

// tip: url较少的时候可以通过if-else去处理,如果url较多,可以自己维护一个url和ViewController的map,加快遍历查找,生成viewController;

if ([URL.host isEqualToString:@“ADetail”]) {

DemoModuleADetailViewController *viewController = [[DemoModuleADetailViewController alloc] init];

if (params[@“key”] != nil) {

viewController.valueLabel.text = params[@“key”];

} else if(params[@“image”]) {

id imageObj = params[@“image”];

if (imageObj && [imageObj isKindOfClass:[UIImage class]]) {

viewController.valueLabel.text = @“this is image”;

viewController.imageView.image = params[@“image”];

[[UIApplication sharedApplication].keyWindow.rootViewController presentViewController:viewController animated:YES completion:nil];

return [UIViewController notURLController];

} else {

viewController.valueLabel.text = @“no image”;

viewController.imageView.image = [UIImage imageNamed:@“noImage”];

[[UIApplication sharedApplication].keyWindow.rootViewController presentViewController:viewController animated:YES completion:nil];

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip1024c (备注前端)
img

最后

其实前端开发的知识点就那么多,面试问来问去还是那么点东西。所以面试没有其他的诀窍,只看你对这些知识点准备的充分程度。so,出去面试时先看看自己复习到了哪个阶段就好。

这里再分享一个复习的路线:(以下体系的复习资料是我从各路大佬收集整理好的)

《前端开发四大模块核心知识笔记》

最后,说个题外话,我在一线互联网企业工作十余年里,指导过不少同行后辈。帮助很多人得到了学习和成长。

CodeChina开源项目:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

你对这些知识点准备的充分程度。so,出去面试时先看看自己复习到了哪个阶段就好。

这里再分享一个复习的路线:(以下体系的复习资料是我从各路大佬收集整理好的)

《前端开发四大模块核心知识笔记》

最后,说个题外话,我在一线互联网企业工作十余年里,指导过不少同行后辈。帮助很多人得到了学习和成长。

CodeChina开源项目:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在IT学习中的很多困惑,所以在工作繁忙的情况下还是坚持各种整理和分享。

  • 24
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值