路由设计

14 阅读3分钟

1. URL 路由方案

这是最常用的一种方案,它借助 URL 格式来表示页面,还能携带参数。

实现步骤如下

  • 注册 URL 与页面的对应关系:可以使用单例或者组件化框架来完成注册。

  • 解析 URL 并进行跳转:在接收到 URL 后,对其进行解析,然后通过反射机制或者工厂模式创建对应的页面。

  • 传递参数:把 URL 中的 query 部分转换为字典,再传递给目标页面。

示例代码如下

objective-c

// 注册路由
[Router registerURLPattern:@"app://detail?id=:id" handler:^UIViewController *(NSDictionary *params) {
    DetailViewController *vc = [[DetailViewController alloc] init];
    vc.itemID = params[@"id"];
    return vc;
}];

// 调用跳转
[Router openURL:@"app://detail?id=123"];

2. 协议 - 实现方案

该方案通过协议来定义服务接口,各模块实现这些接口,从而实现解耦调用。

实现步骤如下

  • 定义协议:明确服务的方法和参数。

  • 注册实现类:将实现类注册到服务中心。

  • 获取服务并调用:通过协议从服务中心获取对应的实现类实例。

示例代码如下

objective-c

// 定义协议
@protocol UserServiceProtocol <NSObject>
- (UIViewController *)userProfileViewControllerWithUserID:(NSString *)userID;
@end

// 注册服务
[ServiceCenter registerService:@protocol(UserServiceProtocol) withClass:[UserServiceImpl class]];

// 调用服务
id<UserServiceProtocol> userService = [ServiceCenter getService:@protocol(UserServiceProtocol)];
UIViewController *vc = [userService userProfileViewControllerWithUserID:@"123"];

3. 数据传递方式

不同的场景可以采用不同的数据传递方式:

基础数据传递

  • URL 参数:适用于简单数据的传递,例如商品 ID、类型等。
  • JSON / 字典:能够传递复杂的数据结构。
  • 单例数据池:可以在全局范围内共享数据。

复杂数据传递

  • Block 回调:用于页面返回时的数据回传。
  • Notification/Delegate:适合一对多或者跨层级的数据传递。
  • Protocol Buffer:适用于跨平台、高性能的数据传输。

4. 路由框架推荐

  • JLRoutes:这是一个轻量级的 URL 路由库,支持正则匹配。
  • CTMediator:基于 Target-Action 的组件化方案,由 Casa 开发。
  • Router:蘑菇街开源的组件化框架,功能十分强大。

5. 实现要点

  • 错误处理:要对未注册的 URL、参数缺失等异常情况进行处理。

  • 生命周期管理:确保被创建的页面能够正确释放。

  • 线程安全:在多线程环境下,注册和调用操作要保证线程安全。

下面是一个结合了 URL 路由和协议实现的综合示例:

objective-c

// 定义商品详情服务协议
@protocol ProductDetailServiceProtocol <NSObject>
- (UIViewController *)productDetailControllerWithParams:(NSDictionary *)params;
@end

// 商品模块实现该协议
@interface ProductServiceImpl : NSObject <ProductDetailServiceProtocol>
@end

@implementation ProductServiceImpl
- (UIViewController *)productDetailControllerWithParams:(NSDictionary *)params {
    ProductDetailViewController *vc = [[ProductDetailViewController alloc] init];
    vc.productID = params[@"productID"];
    vc.title = params[@"title"];
    return vc;
}
@end

// 路由注册
[Router registerURLPattern:@"app://product/detail" handler:^UIViewController *(NSDictionary *params) {    id<ProductDetailServiceProtocol> service = [ServiceCenter getService:@protocol(ProductDetailServiceProtocol)];
    return [service productDetailControllerWithParams:params];
}];

// 调用示例
[Router openURL:@"app://product/detail?productID=456&title=iPhone"];

总结

URL 路由适合页面跳转,而协议实现更适合服务调用。你可以根据项目的规模和需求,选择合适的方案或者组合使用多种方案。

维度路由机制组件通讯
核心目标实现页面跳转和服务调用的解耦实现任意组件间的数据交换和事件通知
常见场景页面导航、服务发现状态同步、事件广播、数据共享
典型方案URL 路由、Protocol - Class 映射Notification、Delegate、Block、RxSwift
数据流向通常是单向的(调用方→被调用方)支持双向通讯和广播
生命周期管理需要管理页面的创建和释放更关注状态的一致性和内存管理