一、关于组件的几个定义
一个不透明的功能实体,能够被第三方组装,且符合一个构件模型。
计算机百科全书:
是软件系统中具有相对独立功能、接口由契约指定、和语境有明显依赖关系、可独立部署、可组装的软件实体。
是一个组装单元,它具有约定式规范的接口,以及明确的依赖环境。构建可以被独立的部署,由第三方组装。
二、为什么要构建组件?
模块
你可能听说过 “组件是天然模块”的说法。好吧,感谢它,我们又要解释这里的术语!
你可能会觉得“组件”的说法更加适合用来描述UI,而“模块”更适合描述提供服务的功能逻辑。而对于我来说,模块和组件意思相近,都提供组织、聚焦和封装,是与某个功能单位相关的。
高内聚
又是一个软件工程的高频词! 我们将相关的一些功能组织在一起,把一切封装起来,而在组件的例子中,就可能是相关的功能逻辑和静态资源:JavaScript、HTML、CSS以及图像等。这就是我们所说的内聚。
这种做法将让组件更容易维护,并且这么做之后,组件的可靠性也将提高。同时,它也能让组件的功能明确,增大组件重用的可能性。
可重用
你看到的示例组件,尤其是Web Component,更关心可重用的问题。功能明确,实现清晰,API易于理解。自然就能促进组件复用。通过构建可重用组件,我们不仅保持了 DRY(不要重复造轮子)原则,还得到了相应的好处。
这里要提醒: 不要过分尝试构建可重用组件。你更应该关注应用程序上所需要的那些特定部分。如果之后相应需求出现,或者组件的确到了可重用的地步,就花一点额外时间让组件重用。事实上,开发者都喜欢去创造可重用功能块(库、组件、模块、插件等),做得太早将会让你后来痛苦不堪。所以,吸取基于组件开发的其他好处,并且接受不是所有组件都能重用的事实。
可互换
一个功能明确好组件的API能让人轻易地更改其内部的功能实现。要是程序内部的组件是松耦合的,那事实上可以用一个组件轻易地替换另一个组件,只要遵循相同的 API/接口/约定。
可组合
之前也讨论过,基于组件的架构让组件组合成新组件更加容易。这样的设计让组件更加专注,也让其他组件中构建和暴露的功能更好利用。
不论是给程序添加功能,还是用来制作完整的程序,更加复杂的功能也能如法炮制。这就是这种方法的主要好处。
是否有必要把所有的东西转换成组件,事实上取决于你自己。没有任何理由让你的程序由 你自己
的组件组合成你最惊叹的功能
,乃至 最花哨的功能
。而这些组件又反过来构成其他组件。如果你从这个方法中得到了好处,就想方设法地去坚持它。然而要注意的是,不要用同样的方法把事情变得复杂,你并不需要过分关注如何让组件重用。而是要关注呈现程序的功能。
三、组件之间的通信
在深入示例之前有必要简单地提到组件间通信的问题。如果组件之间是“独立”、“模块化”的,他们又是如何相互通信的呢?
最显而易见的答案就是让组件间相互引用并通过他们之间的API交互。这样做的问题就在于,这种做法会让组件相互依赖。短期内可能还好,一段时间以后,你在修改程序的时候程序会失控,修改一个组件就会对另一个组件产生极大的影响。决定移除一个不能带来预期价值组件可能会让你的应用程序停止工作,因为它背后会有数个组件依赖于它。
此时,解决方案是提供松耦合的,让组件之间很少或者几乎不知道彼此的方案。组件并不直接创建其他组件,在他们需要通信的时候,他们通过“接口/约定”或者通过 “服务”。。Angular和Ember采用了服务和依赖注入解决这类问题。