美文网首页
iOS中,组件化和模块化的区别是什么?如何实现组件间通信?代码案

iOS中,组件化和模块化的区别是什么?如何实现组件间通信?代码案

作者: 博文得礼 | 来源:发表于2025-07-31 10:37 被阅读0次

一、iOS 中组件化与模块化的区别

1. 定义与核心目标

特性

模块化(Modularization)

组件化(Componentization)

2. 典型场景

• 模块化:将项目拆分为 NetworkModule、UtilsModule、BaseUIKit 等,模块间通过头文件引用通信。

• 组件化:将电商 App 拆分为 HomeComponent、GoodsComponent、CartComponent,每个组件可独立运行,通过路由跳转。

二、组件间通信的实现方式

组件化的核心挑战是解耦组件依赖,常见通信方式如下:

1. 基于协议/代理(Protocol/Delegate)

适用场景:单向通信(如 A 组件调用 B 组件的某个功能)。

优点:强类型约束,编译期检查;缺点:组件间需引入协议头文件,存在间接依赖。

代码案例(Objective-C)

• 定义公共协议(跨组件接口)

// 公共协议(通常放在基础库或中间件中)

@protocol CartComponentProtocol <NSObject>

- (void)showCartViewController; // 展示购物车页面

@end

• B 组件(购物车组件)实现协议

// CartViewController.h

@interface CartViewController : UIViewController <CartComponentProtocol>

- (void)showCartViewController {

    // 展示购物车逻辑

}

@end

• A 组件(首页组件)通过协议调用

// HomeViewController.m

@property (nonatomic, weak) id<CartComponentProtocol> cartDelegate; // 弱引用代理

// 触发通信

[self.cartDelegate showCartViewController];

2. 通知中心(NSNotification / NotificationCenter)

适用场景:一对多广播通信(如全局状态变更通知)。

优点:组件间无直接依赖;缺点:弱类型,运行时风险,难以追踪调用链。

代码案例(Swift)

• B 组件(接收通知)

// CartComponent.swift

NotificationCenter.default.addObserver(

    self,

    selector: #selector(updateCartBadge),

    name: NSNotification.Name("UpdateCartBadge"),

    object: nil

)

@objc func updateCartBadge(notification: NSNotification) {

    guard let count = notification.userInfo?["count"] as? Int else { return }

    // 更新购物车角标

}

• A 组件(发送通知)

// HomeComponent.swift

NotificationCenter.default.post(

    name: NSNotification.Name("UpdateCartBadge"),

    object: nil,

    userInfo: ["count": 5]

)

3. 路由机制(Router Pattern)

适用场景:复杂组件间跳转、参数传递(如页面跳转、服务调用)。

核心思想:通过统一的路由中心,用字符串标识(如 URL 或组件名)映射到具体组件,避免直接依赖。

实现步骤:

1. 定义路由中心(Router)

// Router.h(Objective-C)

@interface Router : NSObject

+ (instancetype)shared;

// 注册组件:将 URL 或组件名映射到类/方法

- (void)registerURLPattern:(NSString *)pattern toClass:(Class)cls;

// 路由跳转:通过 URL 或组件名调用组件功能

- (UIViewController *)openURL:(NSString *)url withParams:(NSDictionary *)params;

@end

// Router.swift(Swift)

class Router {

    static let shared = Router()

    private var routeMap = [String: AnyClass]() // URL 到类的映射

   

    func register(urlPattern: String, to cls: AnyClass) {

        routeMap[urlPattern] = cls

    }

   

    func open(url: String, params: [String: Any] = [:]) -> UIViewController? {

        guard let cls = routeMap[url] as? UIViewController.Type else { return nil }

        let vc = cls.init()

        // 传递参数(需约定参数协议)

        if let paramsVC = vc as? RouteParamsHandler {

            paramsVC.handle(params: params)

        }

        return vc

    }

}

2. 组件注册路由

购物车组件注册页面路由

// CartComponent.m

+ (void)load {

    [[Router shared] registerURLPattern:@"cart://show" toClass:[CartViewController class]];

}

3. 跨组件调用

首页组件通过路由打开购物车

// HomeComponent.m

UIViewController *cartVC = [[Router shared] openURL:@"cart://show" withParams:@{@"userId": @"123"}];

[self.navigationController pushViewController:cartVC animated:YES];

4. 中间件模式(Protocol + 工厂类)

适用场景:组件需暴露复杂服务(如获取数据、操作功能)。

实现:定义中间件协议,组件实现协议,通过工厂类获取实例。

代码案例(Objective-C)

• 定义中间件协议

// UserServiceProtocol.h

@protocol UserServiceProtocol <NSObject>

- (NSString *)getCurrentUserName;

- (void)logout;

@end

• 用户组件实现协议

// UserService.m

@interface UserService : NSObject <UserServiceProtocol>

- (NSString *)getCurrentUserName { return @"张三"; }

- (void)logout { /* 登出逻辑 */ }

@end

• 工厂类获取服务

// ServiceFactory.h

+ (id<UserServiceProtocol>)getUserService {

    // 动态加载用户组件(如通过运行时或配置文件)

    return [[UserService alloc] init];

}

三、组件化实战:路由跳转案例(Objective-C)

1. 组件结构

Project

├─ BaseComponent  // 基础库(含路由中心、公共协议)

├─ HomeComponent  // 首页组件(Target: HomeModule)

├─ CartComponent  // 购物车组件(Target: CartModule)

└─ AppDelegate    // 主工程

2. 路由中心实现(BaseComponent/Router.h)

#import <UIKit/UIKit.h>

@protocol RouteParamsHandler <NSObject>

- (void)handleRouteParams:(NSDictionary *)params;

@end

@interface Router : NSObject

+ (instancetype)shared;

- (void)registerURL:(NSString *)url toViewControllerClass:(Class)vcClass;

- (UIViewController *)openURL:(NSString *)url withParams:(NSDictionary *)params;

@end

3. 购物车组件注册路由(CartComponent/CartViewController.m)

#import "CartViewController.h"

#import "Router.h"

@implementation CartViewController

+ (void)load {

    // 组件加载时注册路由(利用 +load 方法自动执行)

    [[Router shared] registerURL:@"cart://view" toViewControllerClass:self.class];

}

- (void)handleRouteParams:(NSDictionary *)params {

    self.userId = params[@"userId"]; // 接收参数

}

@end

4. 首页组件触发路由跳转(HomeComponent/HomeViewController.m)

#import "HomeViewController.h"

#import "Router.h"

- (IBAction)goToCartButtonTapped:(id)sender {

    UIViewController *cartVC = [[Router shared] openURL:@"cart://view" withParams:@{@"userId": @"123"}];

    [self.navigationController pushViewController:cartVC animated:YES];

}

5. 路由中心实现细节(BaseComponent/Router.m)

#import "Router.h"

@interface Router ()

@property (nonatomic, strong) NSMutableDictionary<NSString *, Class> *routeMap;

@end

@implementation Router

+ (instancetype)shared {

    static dispatch_once_t onceToken;

    static Router *instance;

    dispatch_once(&onceToken, ^{

        instance = [[Router alloc] init];

    });

    return instance;

}

- (void)registerURL:(NSString *)url toViewControllerClass:(Class)vcClass {

    self.routeMap[url] = vcClass;

}

- (UIViewController *)openURL:(NSString *)url withParams:(NSDictionary *)params {

    Class vcClass = self.routeMap[url];

    if (!vcClass) {

        NSLog(@"未找到路由:%@", url);

        return nil;

    }

    UIViewController *vc = [[vcClass alloc] init];

    if ([vc respondsToSelector:@selector(handleRouteParams:)]) {

        [vc performSelector:@selector(handleRouteParams:) withObject:params];

    }

    return vc;

}

@end

四、总结

1. 核心区别:

模块化是“分而治之”,解决代码复用;组件化是“独立自治”,解决复杂业务解耦与团队协作。

2. 通信选择:

简单场景用 协议/代理 或 通知;

复杂场景(如页面跳转、跨组件服务调用)用 路由机制(推荐,解耦最彻底)。

3. 最佳实践:

定义统一的中间件协议或路由规范,避免组件直接依赖;

利用 +load 或初始化方法自动注册组件路由,减少手动配置。

通过组件化与路由机制,可实现“组件独立开发、动态组装”,大幅提升大型项目的可维护性与协作效率。

相关文章

  • iOS模块化-模块间通信

    前言 前面写过一篇《iOS 组件化》,里面介绍了组件化和模块化的区别,模块化可以简单理解为业务模块的组件化。 模块...

  • VUE 爬坑笔记 (3)

    VUE组件 模块化 和 组件化 区别 模块化:从代码角度分析问题,把可复用的代码抽离为单独的模块 好处:方便程序员...

  • vue.js组件初探

    组件的作用 vue.js组件的作用:拆分功能,便于复用。 组件化与模块化的区别: 模块化:从代码逻辑的角度进行划分...

  • iOS组件化储备

    资料 组件化/模块化 蜂鸟商家版 iOS 组件化 / 模块化实践总结 模块化与解耦 浅析 iOS 应用组件化设计 ...

  • Android-模块化、组件化、插件化、热修复-组件化-Butt

    延续上一篇MonkeyLei:Android-模块化、组件化、插件化、热修复-组件化-组件间的通信(本地,下沉,b...

  • 前端面试题

    前端工程化(模块化,组件化) 模块化解决了分而治之的问题 组件化解决了代码复用的问题 src和href的区别 hr...

  • 蜂鸟商家版 iOS 组件化 / 模块化实践总结

    蜂鸟商家版 iOS 组件化 / 模块化实践总结 蜂鸟商家版 iOS 组件化 / 模块化实践总结

  • BeeHive 框架实现原理分析

    BeeHive是什么?BeeHive是阿里提出的在iOS平台上实现模块化编程的一套实现方案。模块化、组件化是目前在...

  • Android模块化探索和实践(3):模块间彻底隔离

    在上一篇文章中Android 模块化探索和实践(2):Dagger2实现模块化(组件化)实现了模块间的Dagger...

  • 任职要求

    1. 精通 iOS 平台的模块化设计架构,能够设计出 SDK 和 UI 组件方案,并实现定制化UI组件界面,动画;...

网友评论

      本文标题:iOS中,组件化和模块化的区别是什么?如何实现组件间通信?代码案

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