前言
在前端开发领域,组件开发⼀直是⼀个绕不开的话题。
那么在组件开发时,要注意哪些问题?如何开发出易维护且复⽤性⾼的组件?
下⾯就结合⾯向对象设计原则,和开发中的实践经验,总结⼀部分组件开发需要注意的⼏个原则。
原则
1、保持简单(KISS—Keep It Simple, Stupid , Straightforward)
代码⾜够简单,也意味着易读、易维护,bug ⽐较难以隐藏。往往简单的设计越⾼效和通⽤(符合奥卡姆剃⼑原理)。
如何满⾜KISS原则?
不要过度优化。⽐如加⼊某些不常⽤的⾼级写法,或者使⽤⼀些过于底层的函数,位运算等。牺牲了可读性和可维护性。
不重复造轮⼦。尽量使⽤经过验证和稳定的库和⽅法。减少维护成本和出错的概率。
不要过度设计(YAGNI—You Ain’t Gonna Need It)。在能保证扩展性的前提下,不要提前设计和编写当前⽤不到的功能。
现在⽤不到的,未来可能也⽤不到。
如果组件是服务于业务的,就尽量让业务需求驱动,⽽不要技术驱动。
2、单⼀职责(SRP—The Single Responsibility Principle)
⼀个组件负责完成⼀个职责/功能。
单⼀职责可以保证组件的粒度,有利于复⽤和维护。如果职责过多,代码就会臃肿,可读性降低,从⽽变得难以维护。
⽐如⽹站的登录和注册功能,从看似有很多相似的元素,但内部的验证的逻辑⼜不尽相同,如果合成⼀个组件就不符合单⼀职责。
但是单⼀职责并没有统⼀的判断依据,通常要结合组件的使⽤场景以及业务发展来看。如果起初不能确定,那就尽量保持组件的简单。
如何粗略判断组件是否符合单⼀职责?
组件代码⾏数、函数个数及属性是否过多。⼀般判断代码是否超过 200 ⾏,函数个数及属性是否已经超过 10 个 。
⽐较难给组件起⼀个合适的名字,说明组件的职责定义不够清晰。
3、不要重复(DRY—Don’t Repeat Yourself)
不要写重复的逻辑,尽量做好代码的复⽤性。这也是开发组件的⽬的之⼀。
但是如果⼀味的消除冗余,很容易⼜违反单⼀职责原则,使组件内部逻辑复杂、难以维护。
所以在⼀些情况下,我们可以利⽤组件化的⽅式,解决重复问题。
当业务中某块逻辑重复过多且具有明确的功能性倾向,我们就应该考虑将其抽象为组件。
当组件之间存在共同依赖同⼀部分逻辑时,我们可以把共同依赖的部分提取为新组件,或者在内部转化为共同依赖。
当两个组件都能实现同⼀功能,且仅因为实现⽅式或接⼝不同时,我们需要将其合并,或者在内部解决为依赖关系。不要提供给⽤户太多选择。
4、共同封闭原则(CCP—The Common-Closure Principle)
将那些会同时修改,或者因为同⼀个⽬的发⽣修改的代码,放到⼀个组件⾥。
举个例⼦,现在有 A、B、C 三个组件,A 和 B 都依赖 C。但是经常 A 的改动就需要改动 C 做⼀些兼容。
这个时候,就适合将 C 组件直接移到到 A 组件中。
的确这样会违背不要重复的原则,但是当可维护性和可复⽤性发⽣冲突时,⼤多数情况可维护性优先级是更⾼的。
5、共同复⽤原则(CRP—The Common Reuse Principle)
⼀个组件中的类应该⼀起被复⽤,相反,如果没有⼀起被复⽤,那就不应该放在⼀个组件。
因此,强烈建议,⼀个组件⼀个类。
6、稳定依赖原则(SDP—The Stable-Dependencies Principle)
不稳定的组件应该依赖于更加稳定的组件。
稳定性的衡量
组件不稳定性指标 = (对别的组件依赖个数) / (对别的组件依赖个数 + 别的组件对⾃⼰依赖个数)
每个组件的不稳定性指标都应该⼤于其依赖组件的不稳定性指标。
在实践中通常是越抽象越稳定,越偏实现越不稳定。(这⾥涉及稳定抽象原则,就不展开了)
举个例⼦, 就像模版页⾯ -> 业务组件 -> 基础组件,依赖关系应该指向更加抽象的⽅向。
7、好莱坞原则(IoC—Inversion of Control, Hollywood Principle)
好莱坞原则就是⼀句话——“don’t call us, we’ll call you.”。意思是,好莱坞的经纪⼈们不希望你去联系他们,⽽是他们会在需要的时候来联系你。
也就是说,所有的组件都是被动的,所有的组件初始化和调⽤都由容器负责。组件处在⼀个容器当中,由容器负责管理。
简单讲,就是控制反转,将⼦组件的创建与管理交给外层容器组件来控制。
8、关注点分离(SoC—Separation of Concerns)
如果⼀个问题能分解为独⽴且较⼩的问题,就是相对较易解决的。
问题太过于复杂,要解决问题需要关注的点太多,⼈的精⼒是有限的,不能同时关注到问题的各个⽅⾯。
通常实现关注点分离的⽅式有两种:⼀种是标准化,另⼀种就是抽象与包装。
标准化下,每个⼈只需按照规范开发组件,⽽不⽤担⼼其他的具体实现。
组件化本⾝就是抽象与包装实现的⼀种⽅式。
⼩结
以上提到的原则,都具有指导意义,但都是理论上的探索,并不是强调组件的开发就必须满⾜每⼀个原则。
组件的开发还有很多其他因素需要考虑,⽐如组件的定位、使⽤场景以及业务发展、开发和维护成本等等。
所有的原则,最终⽬的是帮助我们开发出更具复⽤性,更易维护和扩展的组件。
如果你有⾃⼰的⼀套衡量体系,也欢迎留⾔分享。
• 确保外部调用简单,且有详细的头文件注释说明
• 确保API编码规范,保证风格统一
• 确保API容易扩展,可以考虑预留参数
• 确保没有外部依赖或者尽可能的减少外部依赖,以保证公共库的纯洁.(原则上不能有外部依赖)
• 确保易维护,不存在冗余API
文章持续更新中、希望对各位有所帮助、有问题可留言 大家共同学习.
网友评论