模块、组件和服务分别是什么?它们有什么区别?

组件也叫构件。什么是组件?一个组件就是一个可以独立更换和升级的软件单元。组件具有如下特点:
1 能实现一定功能,或者提供一些服务。
2 不能单独运行,要作为系统的一部分来发挥作用。
3 是物理上的概念,不是逻辑上的概念。
4 可单独维护、可独立升级、可替换而不影响整个系统。
组件是物理上独立的一个东西,它可单独维护、升级、替换,画构件图的目的就是要做系统的构件设计,思考系统在物理上的划分,可利用现有哪些构件,哪些部分可做成构件供以后的项目重用等。

问题1:我们做软件设计时, 往往会提到 “模块 “ 这一词,“模块” 是不是构件呢?
不一定,每个人心中的“模块”的标准是不太一样的,有时候会按业务逻辑来划分模块,有时候从技术的角度来划分。模块只是为了方便说明问题,将软件人为地划分为几个部分而已,我们可以对照组件的上述几个特点来判断 “模块” 是不是构件。

问题2:软件常常会采用分层设计,那一层是一个构件吗?
大部分情况下分层设计中的每一层,仅是一个逻辑上的划分,物理上并不是单独的文件,这时这些分层不是组件。但具体要看实际的设计情况,可对照组件的上述几个特点来判断。

问题3:如何区分“服务”(service)和“组件”(component)?
所谓“组件”是指这样一个软件单元:它将被作者无法控制的其他应用程序使用,但后者不能对组件进行修改。也就是说,使用一个组件的应用程序不能修改组件的源代码,但可以通过作者预留的某种途径对其进行扩展,以改变组件的行为。

服务和组件有某种相似之处:它们都将被外部的应用程序使用。在我看来,两者之间最大的差异在于:组件是在本地使用的软件库(例如JAR文件、程序集、DLL、或者源码导入);而服务是进程外的组件,通过同步或异步的本机进程之间通信或远程接口调用(例如web service、消息系统、RPC,或者socket)这样的机制来被应用程序使用。

服务也可以调用其他服务,因为服务本身也是一个应用程序。

可以把一个个服务映射为一个个运行时的进程,但这仅仅是一个近似。一个服务也可以包括多个进程,比如一个服务应用程序的进程和仅被该服务使用的数据库。

服务可被独立部署。如果一个应用系统由在单个进程中的多个软件库所组成,那么对任一组件做一处修改,都不得不重新部署整个应用系统。但是如果该应用系统被分解为多个服务,那么对于一个服务的多处修改,仅需要重新部署这一个服务,例外是更改服务的接口。

以服务的方式来实现组件化的另一个结果是,能获得更加显式的(explicit)组件接口。

服务的远程调用,比起进程内调用,远程调用更加昂贵。

参考
《微服务》 Martin Fowler
《IoC容器和依赖注入模式》 Martin Fowler
《火球 UML大战需求分析》

复杂性守恒定律 (The Law of Conservation of Complexity or Tesler’s Law)

复杂性守恒定律 (The Law of Conservation of Complexity or Tesler’s Law):系统中存在着一定程度的复杂性,并且不能减少。

系统中的某些复杂性是无意的。这是由于结构不良,错误或者糟糕的建模造成的。这种无意的复杂性可以减少或者消除。然而,由于待解决问题有固有的复杂性,这些复杂性是内在的。这些复杂性可以转移,但不能消除。

该定律有趣的一点是,即使简化整个系统,内在的复杂性也不会降低。它会转移给用户,并且用户必须以更复杂的方式行事。

现实世界的复杂度无法使用代码来消除,如果你想少写代码,就要多写配置;如果你想少写配置,就要多写注解……

业务逻辑无法使用代码来化简或消除,业务逻辑不写在代码里,那就一定会转移到配置文件里或者其他什么地方。

业务逻辑不是程序员能控制的,程序员只负责代码实现,公司的领导层或许可以通过流程再造来改变业务逻辑。

因为现实世界的复杂性无法在代码层面消除,过度地抽象、解耦、套用设计模式反而会增加代码的复杂度。

关于配置文件

配置文件尽量保持简单直白,不要有分支或循环逻辑。分支或循环逻辑应该放到控制器里,因为控制器就是写业务逻辑代码的,改需求改的是控制器里代码,不变化的代码封装在模型里。配置文件里的配置信息应该是控制器的辅助,而不是相反。

由于外部环境的改变而经常跟着改变的变量值应该写在配置文件里,例如数据库配置信息测试环境一套,生产环境另一套,系统环境变量,要启用的进程数、线程数,公司名称、学校名称等,而不要把业务逻辑中的流程控制语句写在配置文件里。

总之,不要过度设计,不要过早优化,等版本稳定下来了再用设计模式重构代码也不迟。当然如果你的项目不缺钱也不缺时间,那么过早优化完全没有问题。

参考

https://github.com/nusr/hacker-laws-zh

https://en.wikipedia.org/wiki/Law_of_conservation_of_complexity

https://ferd.ca/complexity-has-to-live-somewhere.html

https://www.zhihu.com/question/429538225

沃斯定律(Wirth’s Law):软件比硬件更容易变慢

因为软件可不遵循摩尔定律!这也是说明了,当把钱花在硬件上不再能获得线性收益时,就应该招几个大牛程序员(专家)了,把钱花在大牛程序员上,企求带来超线性的收益。

另请参见安达尔定律(Amdahl’s Law)和古斯塔夫森定律(Gustafson’s Law)。