遵循SRP原则拆分数据服务后VC初始化代码臃肿,是否应调整拆分方案?
优化建议
你当前按照单一职责原则拆分「训练存在校验」「训练保存」独立类的设计是完全合理的,不需要取消拆分,初始化代码臃肿的问题本质是依赖组装逻辑放错了位置,而非拆分本身的问题,可通过以下方案优化:
方案1:新增工厂类统一封装依赖组装
把所有依赖的初始化逻辑从ViewController中剥离,放到专门的工厂类中,ViewController只需要调用工厂方法获取Presenter即可,不需要感知内部依赖层级:
enum NewWorkoutFactory { static func makePresenter(delegate: NewWorkoutPresenterDelegate) -> NewWorkoutPresenter { let saveHandler = NewWorkoutDBHandler() let checkHandler = CheckWorkoutDBHandler() let service = NewWorkoutService(newWorkoutDBHandler: saveHandler, checkWorkoutDBHandler: checkHandler) return NewWorkoutPresenter(newWorkoutPresenterDelegate: delegate, newWorkoutService: service) } }
此时ViewController的初始化代码可以简化为:
class ViewController: UIViewController { private lazy var presenter = NewWorkoutFactory.makePresenter(delegate: self) }
这种方案的优势是后续调整依赖结构(比如新增云端校验逻辑、替换数据库实现)时,只需要修改工厂类的代码即可,所有使用Presenter的上层业务侧不需要做任何改动。
方案2:给Service增加默认参数的便捷初始化方法
如果你当前没有多环境切换、单元测试Mock的强需求,可以给NewWorkoutService的初始化方法增加默认参数,默认使用生产环境的DBHandler实现,仅在需要Mock的场景下传入自定义实现:
class NewWorkoutService: NewWorkoutServiceType { convenience init() { self.init(newWorkoutDBHandler: NewWorkoutDBHandler(), checkWorkoutDBHandler: CheckWorkoutDBHandler()) } // 原有全参数初始化方法保留,供测试、自定义场景使用 init(newWorkoutDBHandler: SaveNewWorkoutProtocol, checkWorkoutDBHandler: CheckIfWorkoutExistsProtocol) { self.newWorkoutDBHandler = newWorkoutDBHandler self.checkWorkoutDBHandler = checkWorkoutDBHandler } // ... 原有其他逻辑 }
此时ViewController的初始化代码可以简化为:
class ViewController: UIViewController { private lazy var presenter = NewWorkoutPresenter(newWorkoutPresenterDelegate: self, newWorkoutService: NewWorkoutService()) }
不建议取消拆分的原因
你当前的拆分设计有明确的长期收益:
- 后续迭代修改校验逻辑(比如新增云端重名校验、名字格式校验)、修改保存逻辑(比如新增云端同步、数据加密存储)时,不需要改动对方的代码,符合开闭原则
- 单元测试时可以单独Mock其中一个依赖,比如测试保存逻辑时不需要依赖真实的校验实现,反之亦然,测试成本更低
- 两个独立的DBHandler后续可以被其他业务模块复用,比如其他页面也需要校验训练是否存在时,可以直接复用CheckWorkoutDBHandler,不需要重复写代码
内容的提问来源于stack exchange,提问作者jackbob
相关产品推荐
相关产品推荐

