组件化的核心在于解耦与通信,其基本原理和消息传递实现方案如下:
层级 | 组件类型 | 示例 | 依赖关系 |
---|---|---|---|
应用层 | App壳工程 | MainApp | 依赖业务层 |
业务层 | 垂直业务组件 | UserModule/OrderModule | 依赖基础层 |
基础层 | 公共基础组件 | Network/Storage | 无依赖 |
核心层 | 通用能力 | Router/Logger | 无依赖 |
**.h**
头文件仅暴露必要接口// 注册路由
[Router register:@"myapp://user/profile" handler:^(NSDictionary *params) {
UIViewController *vc = [[UserProfileVC alloc] initWithUserId:params[@"id"]];
[currentNav pushViewController:vc animated:YES];
}];
// 触发路由
[Router open:@"myapp://user/profile?id=1234"];
路由表设计:
@{
@"user/profile" : ^(NSDictionary *p){
return [UserProfileVC new];
},
@"order/detail" : ^(NSDictionary *p){
return [[OrderDetailVC alloc] initWithOrderId:p[@"orderId"]];
}
}
// 定义协议
@protocol UserServiceProtocol <NSObject>
- UIViewController *userProfileVC(NSString *userId);
@end
// 模块实现协议
@interface UserModule : NSObject <UserServiceProtocol>
@end
// 获取服务
id<UserServiceProtocol> service = [ServiceManager serviceFor:@protocol(UserServiceProtocol)];
UIViewController *vc = [service userProfileVC:@"1001"];
// 发送通知
[NSNotificationCenter.default postNotificationName:@"OrderPaidNotification"
object:nil
userInfo:@{@"orderId": @"202307001"}];
// 接收通知(订单模块)
[NSNotificationCenter.default addObserver:self
selector:@selector(handleOrderPaid:)
name:@"OrderPaidNotification"
object:nil];
// 创建全局事件总线
let eventBus = PublishSubject<AppEvent>()
enum AppEvent {
case userLogin(userId: String)
case productAddedToCart(productId: String)
}
// 发送事件
eventBus.onNext(.userLogin(userId: "1001"))
// 订阅事件(购物车模块)
eventBus.filter { $0 == .productAddedToCart }
.subscribe(onNext: { event in
guard case .productAddedToCart(let id) = event else { return }
self.updateCartCount(for: id)
})
// CTMediator调用
UIViewController *vc = [[CTMediator sharedInstance]
performTarget:@"User"
action:@"profileViewController"
params:@{@"userId": @"1001"}];
// 目标模块实现
@implementation Target_User
- UIViewController *action_profileViewController:(NSDictionary *)params {
return [[UserProfileVC alloc] initWithUserId:params[@"userId"]];
}
@end
方案 | 解耦程度 | 类型安全 | 适用场景 | 缺点 |
---|---|---|---|---|
URL路由 | ★★★★ | ★☆ | 页面跳转/深度链接 | 参数无类型校验 |
协议通信 | ★★★☆ | ★★★★ | 模块间服务调用 | 需维护协议文件 |
通知中心 | ★★★★★ | ★☆ | 广播事件/状态同步 | 难以跟踪传递链 |
响应式 | ★★★★☆ | ★★★★ | 数据驱动型应用 | 学习曲线陡峭 |
Target-Action | ★★★★ | ★★★ | 中小型项目 | 参数需手工转换 |
graph BT
App-->业务层
业务层-->服务层
服务层-->基础设施层
subgraph 业务层
用户模块-->|依赖|服务层
订单模块-->|依赖|服务层
end
subgraph 服务层
路由服务-->Router
协议服务-->ServiceManager
事件总线-->EventCenter
end
subgraph 基础设施层
网络-->Networking
存储-->Database
日志-->Logger
end
1. 统一路由中心
// Router.h
@interface Router : NSObject
+ void register:(NSString *)route handler:(UIViewController *(^)(NSDictionary *))block;
+ BOOL open:(NSString *)url;
+ BOOL open:(NSString *)url withParams:(NSDictionary *)params;
@end
// 扩展方法
@interface Router (AppScheme)
+ void openUserProfile:(NSString *)userId;
+ void openOrderDetail:(NSString *)orderId;
@end
2. 协议服务管理器
// ServiceManager.h
@interface ServiceManager : NSObject
+ (void)registerService:(Protocol *)proto implementer:(id)obj;
+ (id)serviceForProtocol:(Protocol *)proto;
@end
// 使用示例
@protocol PaymentService <NSObject>
- void startPayment:(NSString *)orderId amount:(CGFloat)amount;
@end
// 支付模块注册服务
[ServiceManager registerService:@protocol(PaymentService)
implementer:[PaymentManager shared]];
3. 增强型事件总线
// EventCenter.h
@interface EventCenter : NSObject
+ (void)subscribe:(NSString *)event handler:(void (^)(id data))block;
+ (void)publish:(NSString *)event data:(id)data;
+ (void)publish:(NSString *)event data:(id)data delay:(NSTimeInterval)delay;
@end
// 安全订阅(自动解除引用)
#define SUBSCRIBE_EVENT(event, handler) \
[EventCenter subscribe:event handler:^(id data) { \
__strong typeof(self) strongSelf = weakSelf; \
if (strongSelf) { handler(data); } \
}]
// 路由白名单校验
- BOOL canOpenURL:(NSString *)url {
NSArray *allowSchemes = @[@"myapp", @"secureapp"];
NSURLComponents *comp = [NSURLComponents componentsWithString:url];
return [allowSchemes containsObject:comp.scheme];
}
// 协议方法签名验证
- (BOOL)verifyImplementer:(id)obj forProtocol:(Protocol *)proto {
unsigned int methodCount = 0;
struct objc_method_description *methods =
protocol_copyMethodDescriptionList(proto, YES, YES, &methodCount);
for (unsigned int i = 0; i < methodCount; i++) {
if (![obj respondsToSelector:methods[i].name]) {
return NO; // 缺少必须实现的方法
}
}
return YES;
}
// 路由缓存机制
- UIViewController *cachedViewForURL:(NSString *)url {
static NSCache *cache;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
cache = [NSCache new];
cache.countLimit = 20; // 最多缓存20个页面
});
if ([cache objectForKey:url]) {
return [cache objectForKey:url];
}
UIViewController *vc = //...创建实例
[cache setObject:vc forKey:url];
return vc;
}
// Swift兼容层
@objc public class RouterBridge: NSObject {
@objc public static func open(_ url: String) -> Bool {
return Router.open(url)
}
@objc public static func register(
_ url: String,
factory: @escaping ([String: Any]) -> UIViewController
) {
Router.register(url) { params in
return factory(params)
}
}
}
// 自动注册协议(+load方法)
@implementation UserServiceProvider
+ (void)load {
[ServiceManager registerService:@protocol(UserServiceProtocol)
implementer:[self shared]];
}
@end
// 动态加载组件
- void loadModuleIfNeeded:(NSString *)moduleName {
if (![loadedModules containsObject:moduleName]) {
// 从沙盒加载组件bundle
NSBundle *bundle = [NSBundle bundleWithPath:modulePath];
[bundle load];
// 执行模块入口
Class entryClass = [bundle classNamed:@"ModuleEntry"];
[entryClass initializeModule];
}
}
框架 | 核心模式 | 维护方 | 适用场景 | 特点 |
---|---|---|---|---|
BeeHive | 协议注册 | 阿里 | 大型应用 | 支持模块生命周期 |
MGJRouter | URL路由 | 蘑菇街 | 中型应用 | 简单高效 |
CTMediator | Target-Action | Casa | 解耦需求强 | 无依赖注入 |
Swift Composable | 响应式 | 开源 | Swift项目 | 函数式编程 |
DouKit | 混合模式 | 豆瓣 | 混合开发 | 支持Flutter集成 |
关键建议:在大型项目中优先采用 协议通信+路由中心 的混合架构,既保证类型安全又具备灵活性。同时建立完善的 接口版本管理机制,使用 **v1/user/profile**
的路径格式,为后续兼容升级留出空间。