# 前言
最近遇到了一些开发者使用团队内部框架时不太能够接受代码模块化设计理念的问题,因此特此开一篇文章浅谈在软件架构设计中,一些模块化的设计以及复用原则,以便于开发者更好的了解框架模块化设计的思想。
# What‘s 模块?
模块(module)也可以理解为组件,是系统中可服用的功能逻辑封装单位。在不同的架构设计中,模块的概念可能会有所不同。在Golang
中,我们通常将一个package
称为一个模块。
# Why 模块化?
我们进行模块化设计的目的,是为了使得软件功能逻辑间能够尽可能的解耦和复用,其根本是在保证软件开发维护的效率和质量。
# Rule of 模块化
在我们进行开发时,主要是要遵守以下几个原则。
# REP 复用/发布等同原则
复用/发布等同原则(Reuse/Release Equivalency Principle):软件复用的最小粒度应等同于其发布的最小粒度。
“为了复用性而组合”
直白地说,就是要复用一段代码就把它抽成模块。
# CRP 共同复用原则
共同复用原则(Common Reuse Principle):不要强迫一个模块依赖它不需要的东西。
“为了避免不必要的发布而拆分”
相信你一定有这种经历,集成了模块A,但模块A依赖了模块B、C。即使模块B、C 你完全用不到,也不得不集成进来。这是因为你只用到了模块A的部分能力,模块A中额外的能力带来了额外的依赖。如果遵循共同复用原则,你需要把A拆分,只保留你要用的部分。
# CCP 共同闭包原则
共同闭包原则(Common Closure Principle):为了相同目的而同时修改的类,应该放在同一个模块中。
“为了维护性而组合”
对大部分应用程序而言,可维护性的重要性远远大于可复用性,由同一个原因引起的代码修改,最好在同一个模块中,如果分散在多个模块中,那么开发、提交、部署的成本都会上升。
# 权衡
我们在进行模块化设计时,其实很难兼顾上述三个原则,因为这三个原则难以同时满足。
REP 和 CCP 原则会让模块变大,而 CRP 原则会让模块变小。遵守REP、CCP 而忽略 CRP ,就会依赖了太多没有用到的模块和类,而这些模块或类的变动会导致你自己的模块进行太多不必要的发布;遵守 REP 、CRP 而忽略 CCP,因为模块拆分的太细了,一个需求变更可能要改n个模块,带来的成本也是巨大的。
因此我们在设计/开发时,要合理权衡三原则的满足程度。如在项目的早期,CCP 比 REP 更重要。