把同事的代码重写得干净又整洁,老板却让我做回滚?

时间: 2020-02-06阅读: 509标签: 代码

夜深了。

我的同事把这周写的代码提交了。我们在开发一个图形编辑器画布,已经实现了形状调整功能,即通过拖拽形状边缘的手柄来调整形状(比如矩形和椭圆形)。

代码可以运行。

但重复代码有点多。每一种形状(比如矩形和椭圆形)有不同的手柄,往不同方向拖拽手柄对形状的位置和大小影响也不一样。如果用户同时按住 Shift 键,在改变大小的同时要保持比例不变。这里涉及了很多数学运算。

代码看起来像这样:

letRectangle = {
resizeTopLeft(position,size,preserveAspect,dx,dy){
// 10 行重复的数学运算代码
},
resizeTopRight(position,size,preserveAspect,dx,dy){
// 10 行重复的数学运算代码
},
resizeBottomLeft(position,size,preserveAspect,dx,dy){
// 10 行重复的数学运算代码
},
resizeBottomRight(position,size,preserveAspect,dx,dy){
// 10 行重复的数学运算代码
},
};

letOval = {
resizeLeft(position,size,preserveAspect,dx,dy){
// 10 行重复的数学运算代码
},
resizeRight(position,size,preserveAspect,dx,dy){
// 10 行重复的数学运算代码
},
resizeTop(position,size,preserveAspect,dx,dy){
// 10 行重复的数学运算代码
},
resizeBottom(position,size,preserveAspect,dx,dy){
// 10 行重复的数学运算代码
},
};

letHeader = {
resizeLeft(position,size,preserveAspect,dx,dy){
// 10 行重复的数学运算代码
},
resizeRight(position,size,preserveAspect,dx,dy){
// 10 行重复的数学运算代码
},
}

letTextBlock = {
resizeTopLeft(position,size,preserveAspect,dx,dy){
// 10 行重复的数学运算代码
},
resizeTopRight(position,size,preserveAspect,dx,dy){
// 10 行重复的数学运算代码
},
resizeBottomLeft(position,size,preserveAspect,dx,dy){
// 10 行重复的数学运算代码
},
resizeBottomRight(position,size,preserveAspect,dx,dy){
// 10 行重复的数学运算代码
},
};

这些重复代码看起来真的很碍眼。

这样的代码不够干净。

大部分重复是因为朝相同方向调整形状的代码都差不多,比如 Oval.resizeLeft() 和 Header.resizeLeft() 就很类似。

其他重复是因为同一种形状的方法之间很相像,比如 Oval.resizeLeft() 和 Oval 其他的方法就很类似。另外,Rectangle、Header 和 TextBlock 之间也有重复的地方,因为文本框也是矩形。

我想到了一个办法。

我们可以给代码分组,把重复代码移除掉,比如像下面这样。

letDirections = {
top(...) {
// 5 行不一样的数学运算代码
},
left(...) {
// 5 行不一样的数学运算代码
},
bottom(...) {
// 5 行不一样的数学运算代码
},
right(...) {
// 5 行不一样的数学运算代码
},
};

letShapes = {
Oval(...) {
// 5 行不一样的数学运算代码
},
Rectangle(...) {
// 5 行不一样的数学运算代码
},
}

然后,把它们的行为组合起来。

let{top, bottom, left, right} = Directions;

functioncreateHandle(directions){
// 20 行代码
}

letfourCorners =[
createHandle([top,left]),
createHandle([top,right]),
createHandle([bottom,left]),
createHandle([bottom,right]),
];
letfourSides =[
createHandle([top]),
createHandle([left]),
createHandle([right]),
createHandle([bottom]),
];
lettwoSides =[
createHandle([left]),
createHandle([right]),
];

functioncreateBox(shape,handles){
// 20 行代码
}

letRectangle = createBox(Shapes.Rectangle,fourCorners);
letOval = createBox(Shapes.Oval,fourSides);
letHeader = createBox(Shapes.Rectangle,twoSides);
letTextBox = createBox(Shapes.Rectangle,fourCorners);

代码量减少了一半,重复代码完全消失了!多么干净。如果要修改某个形状或方向的行为,只需要在一个地方做出改动,不需要修改所有的方法。

夜已深,我把改好的代码提交到 master 分支,然后上床睡觉。因为帮同事把杂乱的代码清理干净了,我心里还引以为豪。


第二天

事情并没有像我期待的那样发生。

老板找我谈话,他们希望我把代码回滚回去。我感到很惊讶,毕竟原先的代码简直就是一团乱麻,而我改得很干净啊!

我很不情愿地答应了,但几年之后,我才意识到他们其实是对的。


必经之路

痴迷于“干净代码”和删除重复代码是我们很多人都会经历的一个阶段。当我们对自己的代码不是很自信时,就很容易将自我价值感和职业自豪感与一些可以被衡量的东西联系在一起,比如严格的 lint 规则、命名模式、文件结构、不重复代码实践。

我们没办法自动去除重复代码,但可以自己动手做。每次修改代码之后,我们可以很容易地知道重复代码是少了还是多了。所以,去除重复代码感觉就像是在改进代码质量。更糟糕的是,它扰乱了人们的认同感,让他们觉得“我是那种编写干净代码的人”,但这其实无异于自我欺骗。

一旦学会了抽象,我们就很容易对这种能力产生很高的期望,每当看到有重复代码就会想要对它们进行抽象。在写了几年代码之后,我们发现重复代码到处都是,而抽象成了我们获得的一项超级能力。如果有人告诉我们说抽象是一种美德,那我们肯定会深信不疑,并且会因为别人不崇尚“干净代码”而对他们品头论足。

现在,我知道之前的代码重构就是一个灾难,原因如下。

  • 首先,我没有事先和写代码的人沟通。我直接修改了他们的代码并提交,没有和他们讨论。即使这是一种改进(但我现在不这么认为了),但我这样的行事方式并不值得称道。一个健康的工程团队应该以信任为基础,不经过讨论就修改他人的代码会对团队协作造成沉重的打击。

  • 其次,天下没有免费的午餐。我以牺牲灵活性为代价,以此来减少重复代码,这算不上是一个好的权衡。例如,后来我们要求不同形状的不同手柄具备一些特殊的行为,被我重构过的代码需要修改多次才能满足需求,而原先“杂乱”的代码却可以很容易实现这些需求。

那么,我的意思是我们应该尽量写“脏”代码吗?当然不是。我只是建议大家在考虑什么是“干净”或“脏”代码时进行深度思考。你当时有什么样的感觉?厌恶?正义?美丽?优雅?你可以肯定这些品质会带来实质性的工程成果吗?它们又是如何影响代码的编写和修改方式的?

我确实没有深入思考过这些事情。我只考虑到代码本身,但从来没有想过代码与团队之间的演化关系。

编码就像是一段旅程,想想你从写第一行代码到现在走了多远。当第一次通过提取函数或重构类让复杂的代码变简单,我觉得那是一种乐趣。如果你对自己的“杰作”感到自豪,那么就很容易掉入追求干净代码的旋涡。

但请不要止步于此,不要只做一个干净代码狂热者。写出干净的代码并不是我们的终极目标,我们只是通过这种方式尝试找到处理系统复杂性的方法。当你不确定代码改动会对代码库造成怎样的影响,在未知的海洋中需要灯塔的指引,那么这不失为一种防御机制。

写出干净的代码可以作为一种指引,但后面的路还是要自己走。

原文链接:Goodbye clean code!
链接:https://www.infoq.cn/article/dNO484YEeumvC6b6ZNWL
站长推荐

1.云服务推荐: 国内主流云服务商,各类云产品的最新活动,优惠券领取。地址:阿里云腾讯云华为云

2.广告联盟: 整理了目前主流的广告联盟平台,如果你有流量,可以作为参考选择适合你的平台点击进入

链接: http://www.fly63.com/article/detial/7430

关闭

关于 Google 发布的 JS 代码规范

Google为了那些还不熟悉代码规范的人发布了一个JS代码规范。其中列出了编写简洁易懂的代码所应该做的最佳实践。代码规范并不是一种编写正确JavaScript代码的规则,而是为了保持源代码编写模式一致的一种选择。

js高亮显示关键词_页面、搜索关键词高亮显示

页面实现关键词高亮显示:在项目期间遇到一个需求,就是搜索关键词时需要高亮显示,主要通过正则匹配来实现页面关键词高亮显示。在搜索结果中高亮显示关键词:有一组关键词数组,在数组中筛选出符合关键字的内容并将关键字高亮

如何写出优雅的 JS 代码?使用 SOLID 原则

把这六个原则的首字母联合起来(两个 L 算做一个)就是 SOLID (solid,稳定的),其代表的含义就是这六个原则结合使用的好处:建立稳定、灵活、健壮的设计。下面我们来分别看一下这六大设计原则。

你写的代码就是你的犯罪证据

最近我工作的主要内容,是在和别人结对编程,以对一个大型的遗留系统项目进行重构。过程中,我发现一个特别有意思的东西,我重构了很多的 if 语句。

20个编写现代CSS代码的建议

不同于其他很多属性,盒模型中垂直方向上的Margin会在相遇时发生崩塌,也就是说当某个元素的底部Margin与另一个元素的顶部Margin相邻时,只有二者中的较大值会被保留下来,可以从下面这个简单的例子来学习:

tinymce与prism代码高亮实现及汉化的配置

TinyMCE是一个轻量级的基于浏览器的所见即所得编辑器,由JavaScript写成。它对IE6+和Firefox1.5+都有着非常良好的支持。功能方强大,并且功能配置灵活简单。另一特点是加载速度非常快的。

像盖房子一样写代码

像盖房子一样写代码:当我以测试驱动开发的时候,我在想些什么?当我写一个功能模块方法时,我在想些什么?实际上思路可能是在写代码或者写测试的过程中不断的改进和完善的。

看看这些被同事喷的JS代码风格你写过多少?

现在写代码比以前好多了,代码的格式都有eslint,prettier,babel(写新版语法)这些来保证,然而,技术手段再高端都不能解决代码可读性(代码能否被未来的自己和同事看懂)的问题,因为这个问题只有人自己才能解决

减少嵌套,降低代码复杂度

减少嵌套会让代码可读性更好,同时也能更容易的找出bug,开发人员可以更快的迭代,程序也会越来越稳定。简化代码,让编程更轻松!

当一个程序员写不出代码了,该怎么办?

即使是最优秀的程序员也会遭遇无法解决的软件工程问题。碰到这样的问题,并不一定意味着你缺乏技能或知识。编程不是一项容易的工作,我们可以通过采取非正统的方法来保持你想要的生产力水平

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!