五颜六色的代码:论代码的正确位置
问题描述
最近在做一个需求:多个地方的学员姓名保持一致,从技术角度来看就是多个组件中使用从store中取的同一份数据,并且要格式化。
我所采用的方案是 store层的getter + 组件层的 computed和filter ,因为是多个组件都用到这些computed和getter,于是封装了一个mixin。
mixin:
import {mapGetters} from 'vuex';
export default {
computed: {
...mapGetters(['getStudentInfo'])
},
filters: {
formatStudentName(stuName = '') {
return stuName.slice(0, 5);
}
}
}
组件的模板里:
<div>{{getStudentInfo('xxxx') | formatStudentName}}</div>
整体思路就是这样,涉及到的组件比较多,因为我还有别的需求要做,剩下的让小伙伴继续做了。
今天快下班的时候我问了下这里进度咋样了,他说做完了,但是不是用的我那种方式,他觉得每个组件都要写filter太繁琐了,很多组件都要这么写
{{getStudentInfo('xxxx') | formatStudentName}}
于是他修改了store层的getter,把filter的逻辑放到了getter里去:
{
getters:{
getStudentInfo(state) => (id, key = 'name', formatFn) {
formatFn = formatFn || (str) => str.slice(0,5)
return formatFn(state.studentInfo[id][key]);
}
}
}
而且没使用mixin,组件里面直接使用了这个getter
{
computed: {
...mapGetters(['getStudentInfo'])
}
}
<div>{{getStudentInfo(id)}}</div>
分析思路
他觉得这样省掉了调用filter的代码,但我却觉得这种方式不是正确的。
因为这里的格式化是用于显示给用户的,是viewmodel层的逻辑,就算是不想写filter,也应该是在组件层处理,比如添加一个computed。
import {mapGetters} from 'vuex';
export default {
computed: {
...mapGetters(['getStudentInfo']),
getFormatedStudentName() {
return (id) => this.getStudentInfo(id).slice(0, 5);
}
}
}
<div>{{getFormatedStudentName}}</div>
组件里面也同样省掉了filter,但是却不是通过修改store层的getter来做到的。
先不说这里去掉filter有没有必要,关于这段格式化的逻辑应不应该放在getter里,我们进行了讨论,确实,放在getter里看上去也没啥问题,但是这是不那么正确的,并且会导致理解成本的增加。
代码的颜色
如果把viewmodel层、view层、model层的代码分别标记成红绿蓝三种颜色,那么会清晰的看见,在model层里出现了一些viewmodel层的代码。
我们没法对代码标记颜色,但是我们应该有代码分层的意识,按照职能的不同,把代码存放到不同的层次,不同的模块,这样的代码才是整洁易维护的,而不是像大染缸一样,分不清层次,没有约定和规矩。
我们对用户的输入有严格的校验,后端接口对传入的参数也会校验,对于数据,我们会保证正确的基础上,分类存放。其实代码也同样,在正确的基础上,按照职能和架构的不同,把代码归类到不同层次不同模块,泾渭分明,井井有条,这样的代码才是有秩序的易维护的。
总结
讨论一段只用作显示的格式化数据的逻辑应该放在store层还是组件层,分析过程中,通过对代码标记了颜色,理清了代码所应在的位置。
我们接触到的很多难维护的代码就像一个大染缸,很多代码都放错了位置或者封装错了形式,虽然能完成功能,却充满着各种hack的味道,代码难读不说,而不敢随便改,怕牵一发而动全身。
好的代码应该是泾渭分明的,就算代码五颜六色,架构复杂,却丝毫不会乱。