Skip to content

四火的唠叨

一个纯正程序员的啰嗦

Menu
  • 所有文章
  • About Me
  • 关于四火
  • 旅行映像
  • 独立游戏
  • 资源链接
Menu

再谈榔头和钉子

Posted on 02/20/201410/08/2024 by 四火

hammer

不久前写过一篇 《给我一把榔头,满世界都是钉子》,从算法和数据结构的角度谈了谈对于问题和问题解决的工具这两方面我的看法;而最近看到了这样的代码,一个表格,单数行和双数行的样式不同,于是有程序员这样写道:

var trs = $("#spreadSheet tr");
for(var i=0; i<trs.size(); i++){
    if(i%2)
        $(trs.get(i)).children("td").css("color", "RED");
    else
        $(trs.get(i)).children("td").css("color", "GREEN");
}

从功能实现上看,这是一点都没有问题的,JQuery 这把 “榔头”,确实是把这个 “钉子” 给砸进墙里面去了。但问题在于,这是个图书钉,使用了一个建筑工地上用的超大号榔锤。样式的问题,当然优先考虑 CSS 去解决:

#spreadSheet tr:nth-child(odd) td {
	color : GREEN;
}
#spreadSheet tr:nth-child(even) td {
	color : RED;
}

这其实是一个很常见的问题,不同的榔头,应该用来解决不同的问题。类似这样的问题有很多,再比如下面这几组列表的混用:

  • ul/li:无序列表
  • ol/li:有序列表
  • dl/dt/dd:普通列表

w3cshool 中文网站上面有 HTML 标签的详尽列表,虽说基础,但是全部掌握这些语义并在合适的时机使用也并不容易。

如果说,榔头选得不好,依然把钉子砸进去了,只是这个过程有些别扭,那已经是很不错的一个结果了。更糟的可能是,砸完钉子以后无尽的后遗症。我记得刚工作的时候,第一个项目是中国移动的彩铃项目,这类项目都是面向电信运营商的,业务逻辑可谓相当复杂,整个系统大概超过了六十万行代码,但是业务逻辑居然是写在存储过程里的。开山鼻祖的程序员第一次拿存储过程这个榔头砸问题的时候,他大概也没有想到,这会成为名副其实的 “maintenance burden”,后续无尽痛苦的源泉。

关于编程范型

接着我想谈一谈设计模式和编程范型。抽象地说,它们是两种不同角度的对榔头的分类方式。更多的人非常熟悉设计模式(Design Pattern)的含义,大多数设计模式和语言类型、语言本身无关,掌握得好的程序员可以写出简洁、解耦、易维护的代码;半吊子程序员也可以写出概念堆叠、过度设计的代码。

但是编程范型(Programming Paradigm)则往往和语言本身的特性强相关,一种特定的语言,只适用于一种或几种编程范型。简单地说,它类似于一种编程风格,换一种说法,它是问题解决方案落到代码上的表现形式。但是,能否恰当地使用编程范型,决定了能否写出清晰、高效的代码。

我曾经在 《编程的未来》里面提到过编程范型的进化:

很多时候程序员会觉得,算法还是不容易转变成代码,即便是简单的算法,思路简单的纸上实现,变成代码却比较冗长。我觉得大部分情况下这不是你编码技巧的问题,而是编程语言的问题——换句话说,如果你使用一种合适范型的编程语言,兴许就可以轻松解决这个问题——即便这样的语言并不一定好找,并不一定容易设计。

也使用了 Prolog 作为例子。在维基百科的链接上,可以找得到很多编程范型的归类,最常见的几个说出来也会觉得耳熟能详:

  • 声明式编程
  • 事件驱动编程
  • 面向切面编程
  • 管道编程
  • ……

学习一种新的语言,其中一项重要的意义也在于此;有的框架,特别是提供了 DSL 特性的框架,也具备这样的意义。最典型的例子就是写一写前端代码对于程序员来说的意义,我写过一篇 《程序员,都去写一写前端代码吧》,但是其中漏掉了一点,前端的代码(HTML+CSS+JavaScript)带来的编程范型是非常丰富的,尤其是 JavaScript,你可以对比一下 JavaScript 的开源库和 Java 的开源库,Java 的开源库更多的是注重与功能和框架设计,而 JavaScript 的开源库则提供了大量崭新的写代码的风格。我可以不做前端的工作,但是我依然会学 JavaScript。

举例来说,D3,我以前的一位经理说,D3 实在是太反直觉了,不适合用到我们的项目里面去。说反直觉那确实也是正确的,但是很多情况下这是建立在人已有认识的基础上的,一旦熟悉并习惯了 D3 的编程范型(接近于声明式,核心是几个不同的状态,加上状态之间的变迁,而这些变迁的过程可以绑定上丰富的行为),你会发现它的代码可以写得如此优雅和简洁。

文章未经特殊标明皆为本人原创,未经许可不得用于任何商业用途,转载请保持完整性并注明来源链接 《四火的唠叨》

×Scan to share with WeChat

你可能也喜欢看:

  1. 关于 if (someobject != null) 的问题
  2. 借助 AngularJS 写优雅的代码
  3. Java8 集合中的 Lambda 表达式
  4. Backbone.js
  5. 关于接口设计,还有 Fluent Interface,这种有趣的接口设计风格

1 thought on “再谈榔头和钉子”

  1. Anonymous says:
    03/01/2014 at 2:05 AM

    不了解前端编程,但对博主想要转达的思想还有点理解
    一次次的打破约定的范式,找到最适合的是难得的,拥抱变化来进步。

    Reply

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

订阅·联系

四火,啰嗦的程序员一枚,现居西雅图

Amazon Google Groovy Hadoop Haskell Java JavaScript LeetCode Oracle Spark 互联网 亚马逊 前端 华为 历史 同步 团队 图解笔记 基础设施 工作 工作流 工具 工程师 应用系统 异步 微博 思考 技术 数据库 曼联 测试 生活 眼界 程序员 管理 系统设计 缓存 编程范型 美股 英语 西雅图 设计 问题 面向对象 面试

分类

  • Algorithm and Data Structure (30)
  • Concurrency and Asynchronization (6)
  • System Architecture and Design (43)
  • Distributed System (18)
  • Tools Frameworks and Libs (13)
  • Storage and Data Access (8)
  • Front-end Development (33)
  • Programming Languages and Paradigms (55)
  • Testing and Quality Assurance (4)
  • Network and Communication (6)
  • Authentication and Authorization (6)
  • Automation and Operation Excellence (13)
  • Machine Learning and Artificial Intelligence (6)
  • Product Design (7)
  • Hiring and Interviews (14)
  • Project and Team Management (14)
  • Engineering Culture (17)
  • Critical Thinking (25)
  • Career Growth (57)
  • Life Experience and Thoughts (45)

推荐文章

  • 聊一聊分布式系统中的时间
  • 谈谈分布式锁
  • 常见分布式系统设计图解(汇总)
  • 系统设计中的快速估算技巧
  • 从链表存在环的问题说起
  • 技术面试中,什么样的问题才是好问题?
  • 从物理时钟到逻辑时钟
  • 近期面试观摩的一些思考
  • RSA 背后的算法
  • 谈谈 Ops(汇总 + 最终篇):工具和实践
  • 不要让业务牵着鼻子走
  • 倔强的程序员
  • 谈谈微信的信息流
  • 评审的艺术——谈谈现实中的代码评审
  • Blog 安全问题小记
  • 求第 K 个数的问题
  • 一些前端框架的比较(下)——Ember.js 和 React
  • 一些前端框架的比较(上)——GWT、AngularJS 和 Backbone.js
  • 工作流系统的设计
  • Spark 的性能调优
  • “残酷” 的事实
  • 七年工作,几个故事
  • 从 Java 和 JavaScript 来学习 Haskell 和 Groovy(汇总)
  • 一道随机数题目的求解
  • 层次
  • Dynamo 的实现技术和去中心化
  • 也谈谈全栈工程师
  • 多重继承的演变
  • 编程范型:工具的选择
  • GWT 初体验
  • java.util.concurrent 并发包诸类概览
  • 从 DCL 的对象安全发布谈起
  • 不同团队的困惑
  • 不适合 Hadoop 解决的问题
  • 留心那些潜在的系统设计问题
  • 再谈大楼扔鸡蛋的问题
  • 几种华丽无比的开发方式
  • 我眼中的工程师文化
  • 观点的碰撞
  • 谈谈盗版软件问题
  • 对几个软件开发传统观点的质疑和反驳
  • MVC 框架的映射和解耦
  • 编程的未来
  • DAO 的演进
  • 致那些自嘲码农的苦逼程序员
  • Java 多线程发展简史
  • 珍爱生命,远离微博
  • 网站性能优化的三重境界
  • OSCache 框架源码解析
  • “ 你不适合做程序员”
  • 画圆画方的故事

近期评论

  • Ticket: TRANSACTION 1.922915 BTC. Go to withdrawal >> https://yandex.com/poll/enter/BXidu5Ewa8hnAFoFznqSi9?hs=20bd550f65c6e03103876b28cabc4da6& on 倔强的程序员
  • panshenlian.com on 初涉 ML Workflow 系统:Kubeflow Pipelines、Flyte 和 Metaflow
  • panzhixiang on 关于近期求职的近况和思考
  • Anonymous on 闲聊投资:亲自体验和护城河
  • 四火 on 关于近期求职的近况和思考
  • YC on 关于近期求职的近况和思考
  • mafulong on 常见分布式基础设施系统设计图解(四):分布式工作流系统
  • 四火 on 常见分布式基础设施系统设计图解(八):分布式键值存储系统
  • Anonymous on 我裸辞了
  • https://umlcn.com on 资源链接
© 2025 四火的唠叨 | Powered by Minimalist Blog WordPress Theme