为什么需要组件化 单体架构的痛点 ┌─────────────────────────────────────────────────────────┐ │ 单体应用架构 │ ├─────────────────────────────────────────────────────────┤ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ │ 首页 │←→│ 购物车 │←→│ 订单 │←→│ 我的 │ │ │ └────┬────┘ └────┬────┘ └────┬────┘ └────┬────┘ │ │ │ │ │ │ │ │ └────────────┴─────┬──────┴────────────┘ │ │ ↓ │ │ ┌─────────────────────────────────────────────────┐ │ │ │ 公共代码 & 工具类 │ │ │ │ (网络层、数据库、工具类、基础UI 全部耦合在一起) │ │ │ └─────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────┘ 问题: ❌ 编译时间长(修改一行代码需全量编译) ❌ 代码冲突频繁(多人协作噩梦) ❌ 业务边界模糊(功能交叉,职责不清) ❌ 无法独立测试(牵一发动全身) ❌ 技术债务累积(代码腐化严重)组件化目标 ┌─────────────────────────────────────────────────────────┐ │ 组件化架构 │ ├─────────────────────────────────────────────────────────┤ │ 独立开发 │ 独立测试 │ 独立发布 │ 快速编译 │ ├─────────────────────────────────────────────────────────┤ │ │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ │ 首页组件 │ │ 购物车组件│ │ 订单组件 │ 业务层 │ │ └────┬────┘ └────┬────┘ └────┬────┘ │ │ │ │ │ │ │ ─────┴─────────────┴─────────────┴───── │ │ ↓ │ │ ┌─────────────────────────────────────┐ │ │ │ 组件通信中间件 │ 中间层 │ │ └─────────────────────────────────────┘ │ │ ↓ │ │ ┌────────┐ ┌────────┐ ┌────────┐ │ │ │ 网络库 │ │ 数据库 │ │ 工具库 │ 基础层 │ │ └────────┘ └────────┘ └────────┘ │ └─────────────────────────────────────────────────────────┘组件化基础概念 组件分类 /* 组件分层金字塔 ┌──────────────┐ │ 壳工程 │ ← 主App,负责组装 │ (Host) │ └──────┬───────┘ │ ┌─────────────┼─────────────┐ │ │ │ ┌───▼───┐ ┌────▼────┐ ┌────▼────┐ │首页业务│ │购物车业务 │ │ 我的业务 │ ← 业务组件 └───┬───┘ └────┬────┘ └────┬────┘ │ │ │ └────────────┼─────────────┘ │ ┌────────────┼────────────┐ │ │ │ ┌───▼───┐ ┌───▼───┐ ┌────▼────┐ │ 分享 │ │ 支付 │ │ 登录 │ ← 功能组件 └───┬───┘ └───┬───┘ └────┬────┘ │ │ │ └───────────┼────────────┘ │ ┌───────────┼───────────┐ │ │ │ ┌───▼───┐ ┌───▼───┐ ┌────▼────┐ │ 网络库 │ │ UI库 │ │ 工具库 │ ← 基础组件 └───────┘ └───────┘ └─────────┘ */ // MARK: - 基础组件示例 /// 基础组件:无业务属性,纯技术能力封装 public class NetworkKit { public static let shared= NetworkKit ( ) public func request< T: Decodable > ( _ endpoint: Endpoint , responseType: T. Type ) asyncthrows - > T{ // 网络请求实现 } } // MARK: - 功能组件示例 /// 功能组件:可复用的业务功能 public class ShareKit { public static func share ( content: ShareContent , from viewController: UIViewController , completion: @escaping( Result < Void , Error > ) - > Void ) { // 分享实现 } } // MARK: - 业务组件示例 /// 业务组件:具体业务模块 public class HomeModule : ModuleProtocol { public static func initialize ( ) { // 模块初始化 } public static func createViewController ( ) - > UIViewController { return HomeViewController ( ) } } 组件依赖原则 依赖规则图示: ┌─────────────┐ │ 业务层 │ 最上层 └──────┬──────┘ │ 依赖 ▼ ┌─────────────┐ │ 功能层 │ 中间层 └──────┬──────┘ │ 依赖 ▼ ┌─────────────┐ │ 基础层 │ 最底层 └─────────────┘ 规则: ✅ 上层可以依赖下层 ✅ 同层之间通过协议/中间件通信 ❌ 下层不可依赖上层 ❌ 禁止循环依赖模块拆分策略 拆分维度分析 /* 模块拆分考虑因素: 1. 业务边界 ┌────────────────────────────────────────────┐ │ 电商App业务域划分 │ ├────────────┬────────────┬─────────────────┤ │ 商品域 │ 交易域 │ 用户域 │ │ ├─商品详情 │ ├─购物车 │ ├─登录注册 │ │ ├─商品搜索 │ ├─订单 │ ├─个人中心 │ │ └─商品分类 │ └─支付 │ └─消息通知 │ └────────────┴────────────┴─────────────────┘ 2. 团队结构 ┌────────────────────────────────────────────┐ │ 按团队划分模块 │ ├────────────┬────────────┬─────────────────┤ │ A团队 │ B团队 │ C团队 │ │ 负责首页 │ 负责交易 │ 负责用户 │ └────────────┴────────────┴─────────────────┘ 3. 变更频率 ┌────────────────────────────────────────────┐ │ 高频变更 → 独立组件,快速迭代 │ │ 低频变更 → 可合并,减少维护成本 │ └────────────────────────────────────────────┘ */ // MARK: - 模块拆分示例 /// 业务模块定义 enum BusinessModule : String , CaseIterable { case home= "Home" // 首页模块 case product= "Product" // 商品模块 case cart= "Cart" // 购物车模块 case order= "Order" // 订单模块 case user= "User" // 用户模块 case message= "Message" // 消息模块 /// 模块优先级(用于启动顺序) var priority: Int { switch self { case . user: return 100 // 用户模块最先初始化 case . message: return 90 case . home: return 80 case . product: return 70 case . cart: return 60 case . order: return 50 } } } /// 功能模块定义 enum FeatureModule : String { case share= "Share" // 分享 case payment= "Payment" // 支付 case push= "Push" // 推送 case analytics= "Analytics" // 数据统计 case imageLoader= "Image" // 图片加载 } /// 基础模块定义 enum CoreModule : String { case network= "Network" // 网络 case database= "Database" // 数据库 case cache= "Cache" // 缓存 case log= "Log" // 日志 case router= "Router" // 路由 } Podfile 组织结构 # Podfile 组件化配置示例 platform:ios , '13.0' use_frameworks! inhibit_all_warnings! # ======================== # 组件源配置 # ======================== source'https://github.com/CocoaPods/Specs.git' # 公共源 source'https://your-company.com/ios-specs.git' # 私有源 # ======================== # 抽象目标 - 公共依赖 # ======================== abstract_target'CommonPods' do # 基础层组件 pod'CoreNetwork' , '~> 1.0' pod'CoreDatabase' , '~> 1.0' pod'CoreCache' , '~> 1.0' pod'CoreLogger' , '~> 1.0' pod'CoreRouter' , '~> 1.0' pod'CoreUIKit' , '~> 1.0' # 功能层组件 pod'FeatureShare' , '~> 1.0' pod'FeaturePayment' , '~> 1.0' pod'FeaturePush' , '~> 1.0' # 主工程 target'MainApp' do # 业务层组件 pod'BizHome' , '~> 1.0' pod'BizProduct' , '~> 1.0' pod'BizCart' , '~> 1.0' pod'BizOrder' , '~> 1.0' pod'BizUser' , '~> 1.0' pod'BizMessage' , '~> 1.0' target'MainAppTests' do inherit! :search_paths pod'Quick' pod'Nimble' end end # 组件独立调试工程 target'BizHomeDemo' do pod'BizHome' , :path = > '../BizHome' end target'BizProductDemo' do pod'BizProduct' , :path = > '../BizProduct' end end # ======================== # Post Install Hook # ======================== post_installdo | installer| installer. pods_project. targets. each do | target| target. build_configurations. each do | config| config. build_settings[ 'IPHONEOS_DEPLOYMENT_TARGET' ] = '13.0' # 开启模块稳定性 config. build_settings[ 'BUILD_LIBRARY_FOR_DISTRIBUTION' ] = 'YES' end end end 组件 Podspec 规范 # BizHome.podspec - 业务组件规范 Pod : : Spec . new do | s| s. name= 'BizHome' s. version= '1.0.0' s. summary= '首页业务组件' s. description= < < - DESC 首页业务组件,包含:- 首页推荐流- Banner 轮播- 分类入口- 活动专区DESC s. homepage= 'https://your-company.com/BizHome' s. license= { :type = > 'MIT' , :file = > 'LICENSE' } s. author= { 'iOS Team' = > 'ios@company.com' } s. source= { :git = > 'https://github.com/company/BizHome.git' , :tag = > s. version. to_s} s. ios. deployment_target= '13.0' s. swift_version= '5.0' # 源码 s. source_files= 'BizHome/Classes/**/*' # 资源文件 s. resources= 'BizHome/Assets/**/*' s. resource_bundles= { 'BizHomeBundle' = > [ 'BizHome/Assets/*.xcassets' , 'BizHome/Assets/*.xib' ] } # 公开头文件(给其他组件使用的接口) s. public_header_files= 'BizHome/Classes/Public/**/*.h' # ======================== # 依赖声明(关键!) # ======================== # 只依赖协议层,不依赖具体实现 s. dependency'ServiceProtocols' , '~> 1.0' # 依赖基础组件 s. dependency'CoreUIKit' , '~> 1.0' s. dependency'CoreNetwork' , '~> 1.0' s. dependency'CoreRouter' , '~> 1.0' # 依赖功能组件(通过协议) # 注意:不直接依赖 BizProduct、BizCart 等业务组件! # ======================== # 子模块划分 # ======================== s. subspec'Core' do | core| core. source_files= 'BizHome/Classes/Core/**/*' end s. subspec'UI' do | ui| ui. source_files= 'BizHome/Classes/UI/**/*' ui. dependency'BizHome/Core' end s. default_subspecs= 'Core' , 'UI' end 依赖反转原则 依赖反转核心思想 传统依赖 vs 依赖反转 【传统依赖】 ┌─────────────┐ ┌─────────────┐ │ 首页模块 │ ──────→ │ 商品模块 │ │ (高层模块) │ 依赖 │ (低层模块) │ └─────────────┘ └─────────────┘ 问题:首页直接依赖商品模块,耦合严重 【依赖反转】 ┌─────────────┐ ┌─────────────────┐ │ 首页模块 │ ──────→ │ 商品服务协议 │ │ (高层模块) │ 依赖 │ (抽象) │ └─────────────┘ └────────┬────────┘ │ │ 实现 │ ┌────────▼────────┐ │ 商品模块 │ │ (具体实现) │ └─────────────────┘ 优势: ✅ 高层模块不依赖低层模块 ✅ 两者都依赖抽象 ✅ 抽象不依赖细节 ✅ 细节依赖抽象协议层设计 // MARK: - 服务协议层(独立Pod: ServiceProtocols) // ═══════════════════════════════════════════════════════ // 商品服务协议 // ═══════════════════════════════════════════════════════ /// 商品信息模型(协议层定义,与具体模块无关) public struct ProductInfo : Codable , Hashable { public let id: String public let name: String public let price: Decimal public let imageURL: URL ? public let description: String public let stock: Int public init ( id: String , name: String , price: Decimal , imageURL: URL ? , description: String , stock: Int ) { self . id= idself . name= nameself . price= priceself . imageURL= imageURLself . description= descriptionself . stock= stock} } /// 商品服务协议 public protocol ProductServiceProtocol { /// 获取商品详情 func fetchProduct ( by id: String ) asyncthrows - > ProductInfo /// 获取商品列表 func fetchProducts ( category: String , page: Int , pageSize: Int ) asyncthrows - > [ ProductInfo ] /// 搜索商品 func searchProducts ( keyword: String ) asyncthrows - > [ ProductInfo ] /// 获取商品详情页 func productDetailViewController ( productId: String ) - > UIViewController } // ═══════════════════════════════════════════════════════ // 购物车服务协议 // ═══════════════════════════════════════════════════════ /// 购物车项模型 public struct CartItem : Codable , Identifiable { public let id: String public let productId: String public let productName: String public let price: Decimal public var quantity: Int public let imageURL: URL ? public init ( id: String , productId: String , productName: String , price: Decimal , quantity: Int , imageURL: URL ? ) { self . id= idself . productId= productIdself . productName= productNameself . price= priceself . quantity= quantityself . imageURL= imageURL} } /// 购物车服务协议 public protocol CartServiceProtocol { /// 添加商品到购物车 func addToCart ( productId: String , quantity: Int ) asyncthrows /// 从购物车移除商品 func removeFromCart ( itemId: String ) asyncthrows /// 更新购物车商品数量 func updateQuantity ( itemId: String , quantity: Int ) asyncthrows /// 获取购物车列表 func fetchCartItems ( ) asyncthrows - > [ CartItem ] /// 获取购物车商品数量(用于Tab角标) func cartItemCount ( ) - > Int /// 购物车数量变化通知 var cartCountPublisher: AnyPublisher < Int , Never > { get } } // ═══════════════════════════════════════════════════════ // 用户服务协议 // ═══════════════════════════════════════════════════════ /// 用户信息模型 public struct UserInfo : Codable { public let userId: String public let nickname: String public let avatar: URL ? public let phone: String ? public let isVip: Bool public init ( userId: String , nickname: String , avatar: URL ? , phone: String ? , isVip: Bool ) { self . userId= userIdself . nickname= nicknameself . avatar= avatarself . phone= phoneself . isVip= isVip} } /// 登录状态 public enum LoginState { case notLogincase loggingcase logged ( UserInfo ) case expired} /// 用户服务协议 public protocol UserServiceProtocol { /// 当前登录状态 var currentState: LoginState { get } /// 登录状态变化发布者 var statePublisher: AnyPublisher < LoginState , Never > { get } /// 获取当前用户信息 func currentUser ( ) - > UserInfo ? /// 是否已登录 func isLoggedIn ( ) - > Bool /// 登录 func login ( phone: String , code: String ) asyncthrows - > UserInfo /// 登出 func logout ( ) asyncthrows /// 展示登录页面 func presentLoginIfNeeded ( from viewController: UIViewController , completion: @escaping( Bool ) - > Void ) } // ═══════════════════════════════════════════════════════ // 订单服务协议 // ═══════════════════════════════════════════════════════ /// 订单状态 public enum OrderStatus : String , Codable { case pending= "pending" // 待支付 case paid= "paid" // 已支付 case shipping= "shipping" // 配送中 case delivered= "delivered" // 已送达 case completed= "completed" // 已完成 case cancelled= "cancelled" // 已取消 } /// 订单信息 public struct OrderInfo : Codable , Identifiable { public let id: String public let orderNo: String public let status: OrderStatus public let totalAmount: Decimal public let items: [ OrderItem ] public let createTime: Date public struct OrderItem : Codable { public let productId: String public let productName: String public let price: Decimal public let quantity: Int } } /// 订单服务协议 public protocol OrderServiceProtocol { /// 创建订单 func createOrder ( from cartItems: [ CartItem ] , addressId: String ) asyncthrows - > OrderInfo /// 获取订单列表 func fetchOrders ( status: OrderStatus ? , page: Int ) asyncthrows - > [ OrderInfo ] /// 获取订单详情 func fetchOrderDetail ( orderId: String ) asyncthrows - > OrderInfo /// 取消订单 func cancelOrder ( orderId: String ) asyncthrows /// 订单详情页 func orderDetailViewController ( orderId: String ) - > UIViewController } // ═══════════════════════════════════════════════════════ // 路由服务协议 // ═══════════════════════════════════════════════════════ /// 路由路径定义 public enum RoutePath { case homecase productDetail ( productId: String ) case productList ( category: String ) case cartcase order ( orderId: String ) case orderList ( status: OrderStatus ? ) case userCentercase logincase webView ( url: URL , title: String ? ) case custom ( path: String , params: [ String : Any ] ) public var pathString: String { switch self { case . home: return "/home" case . productDetail ( let id) : return "/product/\( id) " case . productList ( let category) : return "/products?category=\( category) " case . cart: return "/cart" case . order ( let id) : return "/order/\( id) " case . orderList: return "/orders" case . userCenter: return "/user" case . login: return "/login" case . webView ( let url, _ ) : return "/web?url=\( url. absoluteString) " case . custom ( let path, _ ) : return path} } } /// 路由服务协议 public protocol RouterServiceProtocol { /// 注册路由处理器 func register ( path: String , handler: @escaping( URL , [ String : Any ] ) - > UIViewController ? ) /// 导航到指定路径 func navigate ( to path: RoutePath , from viewController: UIViewController ? , animated: Bool ) /// 通过URL导航 func open ( url: URL , from viewController: UIViewController ? ) /// 返回 func goBack ( from viewController: UIViewController , animated: Bool ) /// 返回到根视图 func popToRoot ( from viewController: UIViewController , animated: Bool ) } 服务注册与发现 // MARK: - 服务容器(依赖注入容器) /// 服务容器 - 单例模式 public final class ServiceContainer { public static let shared= ServiceContainer ( ) private var services: [ String : Any ] = [ : ] private var factories: [ String : ( ) - > Any ] = [ : ] private let lock= NSRecursiveLock ( ) private init ( ) { } // ═══════════════════════════════════════════════════════ // 注册服务 // ═══════════════════════════════════════════════════════ /// 注册服务实例(单例模式) public func register< T> ( _ type: T. Type , instance: T) { lock. lock ( ) defer { lock. unlock ( ) } let key= String ( describing: type) services[ key] = instanceprint ( "📦 [ServiceContainer] Registered:\( key) " ) } /// 注册服务工厂(每次获取创建新实例) public func registerFactory< T> ( _ type: T. Type , factory: @escaping( ) - > T) { lock. lock ( ) defer { lock. unlock ( ) } let key= String ( describing: type) factories[ key] = factoryprint ( "🏭 [ServiceContainer] Registered Factory:\( key) " ) } /// 注册服务工厂(懒加载单例) public func registerLazy< T> ( _ type: T. Type , factory: @escaping( ) - > T) { lock. lock ( ) defer { lock. unlock ( ) } let key= String ( describing: type) factories[ key] = { [ weak self ] in if let existing= self ? . services[ key] as ? T{ return existing} let instance= factory ( ) self ? . services[ key] = instancereturn instance} print ( "💤 [ServiceContainer] Registered Lazy:\( key) " ) } // ═══════════════════════════════════════════════════════ // 获取服务 // ═══════════════════════════════════════════════════════ /// 获取服务(可选) public func resolve< T> ( _ type: T. Type ) - > T? { lock. lock (