终于完成了公司的一个大project,这期间的收获也非常多,对于“组件化开发”有了更深一层的心得体会。
在如今的前端开发中,“组件化”已经成为了一种流行,随之而来的各种开发框架更是把这一概念发扬光大。但是概念归概念,真正的“组件化”实践还是有许多值得探讨的地方,其中“黑箱”是我认为最具有代表性的实践方式。今天就让我们抛开具体的框架,直接来谈一谈“组件化开发”与“黑箱”。
一、组件化
首先引用维基百科的一段介绍:
基于组件的软件工程(Component-based software engineering,简称CBSE)或基于组件的开发(Component-Based Development,简称CBD)是一种软件开发范型。它是现今软件复用理论实用化的研究热点,在组件对象模型的支持下,通过复用已有的构件,软件开发者可以“即插即用”地快速构造应用软件。这样不仅可以节省时间和经费,提高工作效率,而且可以产生更加规范、更加可靠的应用软件。
在业务的开发中,我们往往会把一些需要复用的部分抽取出来单独封装,在需要的时候再引入使用。这样就相当于把这可复用的部分进行了“组件化”。组件化的操作能够大大减少开发量,同时一个好的组件也能有效提升稳定性。在现代化的web开发中,“组件”通常包含了逻辑功能和样式,各种各样的UI库正是最好的例子。比如一个交互复杂的下拉菜单,如果每次使用前都要重新写一套代码,将会徒增巨大的时间与人力成本。而通过UI库,只需要简单地引入,按照约定的写法引用即可,大大解放了生产力。
除此之外,“组件化”能够有效降低甚至消除耦合。我们知道“牵一发而动全身”,如果一个系统各模块之间耦合太紧,一旦有个地方出现问题,排查起来将会非常困难,其后果可能是灾难性的。而“组件化”的思路能够很好地避免这个问题。因为组件之间是相互独立,仅仅通过接口相联系,一旦某个组件出现问题,只需要排查这个组件的故障即可,其他组件完全可以正常工作,或者等待这个组件修复后再工作。
二、纯函数
维基百科定义:
在程序设计中,若一个函数符合以下要求,则它可能被认为是纯函数:
- 此函数在相同的输入值时,需产生相同的输出。函数的输出和输入值以外的其他隐藏信息或状态无关,也和由I/O设备产生的外部输出无关。
- 该函数不能有语义上可观察的函数副作用,诸如“触发事件”,使输出设备输出,或更改输出值以外物件的内容等。
从数学来说,若定义一个函数:
f(x) = x + x
那么不管何时何地任何条件,只要我输入1,那么一定会输出2:
f(1) == 2
正是因为这种“纯”的特性,所以允许对其进行“高阶”:
f(x) = x + xg(x) = x * 2h(x) = x * xh(g(f(1))) = 16
网络上对于纯函数和函数式编程的文章非常丰富,本文就不再赘述了。从我个人角度出发,只要能理解什么是“纯”即可。
三、黑箱
继续引用维基百科的一句话介绍:
黑箱,指一个只知道输入输出关系而不知道内部结构的系统或设备。
生活中的很多东西都可以理解为“黑箱”,比如我们常用的手机,我们可能不知道它到底是怎么运行的,只知道我的手指划过,它就会作出相应的动作,这时,手指划过就是“输入”,相应的动作就是“输出”。因为输入输出如此直观简单,所以手机能够被所有人轻松地使用。
我们的工作离不开电脑,现在电脑只要插上电源开机就能用,但是人类历史上的第一台电脑,却是要专业人士花费一番功夫才能运行的庞然大物——因为使用者需要完全弄懂这台机器的内部运行原理,才能够正确地使用它。
上述的两个例子,其实都是为了阐述一个观点:黑箱更有利于使用。
但是,凡事都具有两面性。黑箱是牺牲了使用者对于其内部构造和原理的认识,换来的易用性。如果黑箱内部出现故障,那么使用者无法得知具体原因,这个对于系统故障的排查非常不利。所以黑箱对于系统的稳定性、可靠性的要求非常高。
四、工程实践
经过前文的三个小节,应该不难理解我想表达的观点。一个黑箱就是一个纯函数,抽象出来的组件理应符合这种黑箱的设定:
-
组件之间仅通过接口联系
一个组件可以接收多个参数,组件的嵌套和使用也是通过接口进行。组件在处理完传入的参数后,应当把结果通过接口(或者事件)传递出去,而不能直接影响外部。比如下面这个例子,经过f(x)
的处理,外部的num
并不会被改变。num = 1f(x) = x + 1// f(num) => 2// num => 1
- 组件内部的运行原理不对用户开放很容易理解,组件应当是一个黑箱,用户无需关注内部的实现原理。当然,组件应该保证高度的稳定性和可靠性。
- 组件的输入输出完全确定结合“纯函数”和“黑箱”的概念,一个组件应当是可预测的(predictable),只有完全确定的输入输出才能保证。因此在工程实践中,强制规定输入的数据类型、变量名之类的内容是非常必须的。
后记
组件化的开发还有许多最佳实践,比如涵盖了一定逻辑功能的“业务组件”也是值得探讨的地方。本文仅为个人在开发时的一些感悟,权当抛砖引玉,欢迎各位读者和我共同交流~感谢阅读~~~