我拒绝接受的几个最佳编程实践方法

import类,而不是import整个包

在很多语言里,这通常是一种被推荐的做法,有些甚至是必须的。如果是在C++里,这还算是有点意义,因为更少 #include 意味着更快的编译速度,然而,这种意义仅体现在需要花很长时间去编译的大型项目中。

而对很多像Java这样的语言,这毫无意义。因为它不影响编译的时间,所有你得到的回报只是花更多的努力来维护你的import语句。虽然IDE可以帮助你做这些事情,但你仍然需要时不时的多点几次鼠标/键盘,在版本控制系统里多留几条变更记录,干扰你的代码审查。有什么实际用处?向官僚机构表明代码很规范,无它用途。

面向接口编程

这项编程法则要求程序员定义接口,并针对接口来编程,而不是针对实现编程。理由非常简单:容易开发第二种实现,易于测试(真的吗?),更有效的使用代码。

问题就出在你不能凡事都按照这个原则。我个人认为,如果一个方法需要有多个实现,那使用接口是不二选择。但除此之外,如果你仍遵守的话,除了增加代码量,增添麻烦外,不会有任何好处。而且,把一个类重构成接口和它的实现并不困难,事实上是非常简单,所以,为什么一开始就要写接口呢,当需要时把它改造成接口也不晚。

禁用某种语言功能

在很多企业、组织使用的编码规范中,你会发现各种各样的类似于“不要使用goto语句”,“不要使用三元操作符”等规则。

如果一种语言的某种语法并未标志为“deprecated”,为什么不让人使用?当然,要正确的使用!即使像 goto 这样的语法同样可以让代码更可读、更易理解——只要你能以正确的方式、用在正确的地方。

使用Setters/getters,禁止public属性

这是最著名的Java风格,Java里任何公有属性都是不提倡的,任何属性都应该通过 setters 和 getters 操作,不允许有任何质疑。有些共用框架更加强化了这些。每次当我看到一个5年前的老类里只有一些私有属性和公有的无聊的 setters 和 getters ,我都会奇怪这是要干嘛?是为了增加代码量?是为了预防将来有可能出现意外的属性值修改?但是如果真的有人修改了,这又能起到什么预防效果?

单个返回语句

有人说多个返回语句会让代码变复杂。我发现却正好完全相反。当方法/函数在退出之前需要做一些收尾工作时,单一return语句会让函数更简单,但在其它很多情况下,这反而会让事情变得复杂,你需要添加额外的if-else来处理各种非正常退出情况。

尽量责任分离

我这里主要是针对“尽量”。有些人把这做到了极限,甚至有些变态。没错,把大的复杂的问题拆分成小的简单问题,这很好。但拆的太小就会引起新的问题。如果你把一棵树砍成牙签那么大小的块,你得到的就是一堆垃圾。

有些问题本身就是很复杂,你无法通过拆解来让它变简单。

为了让这篇文章有个比较积极的结尾,下面是我认为的放之四海皆准的最佳实践方法:

  • 做任何事情都要有个理由
  • 如果你做的未能符合预期,重做,替换方法或给予修正
  • 扔掉垃圾通常是你最应该做的事情——不论这垃圾造价多高
收藏 11 评论

相关文章

可能感兴趣的话题



直接登录
最新评论
  • thoupin   2013/08/13

    使用Setters/getters,禁止public属性

    这是最著名的Java风格,Java里任何公有属性都是不提倡的,任何属性都应该通过 setters 和 getters 操作,不允许有任何质疑。有些共用框架更加强化了这些。每次当我看到一个5年前的老类里只有一些私有属性和公有的无聊的 setters 和 getters ,我都会奇怪这是要干嘛?是为了增加代码量?是为了预防将来有可能出现意外的属性值修改?但是如果真的有人修改了,这又能起到什么预防效果?

    以前我也这么想过,但一闪而过而已。

    编程不能为了规范而规范,本末倒置的时候往往连自己都不知道

  • alex   2013/08/13

    getter/setter显然在没有用的时候,确实没什么用,但是,一旦getter/setter本身有某些逻辑的时候,比如会和某个Manager类进行通信,或者设置一些dirty标志时,就很有用,你可能就会觉得当初的封装是值得的。

    • 小侯yeah   2013/08/14

      在 Java 中,应该避免在 getter/setter 代码中进行逻辑操作
      一方面原因是是由于大部分程序员看到方法名是 getter 和 setter 时不会认为里面还有逻辑操作,这样的命名会干扰读者对代码的理解
      另外,getter/setter 从名称看来就是没有逻辑操作的方法,如果在这里面进行裸机操作,那么至少是方法名和方法内容并不一致,命名不良

      • 小侯yeah   2013/08/14

        上面说到的逻辑操作是指业务逻辑的处理,但一些安全问题很适合放在 getter 和 setter 方法中

        比如,为保护原始数据不被修改, getter 方法可以返回一个等值的新对象,这是很常用的方法。或者在处理多线程访问时,在 set 中可能需要处理加锁、同步之类的问题
        如果把属性直接public掉,就导致了属性的安全问题成为所有调用者的工作,使得代码安全性难以 review

        原文吐槽的是 setter/getter 成为不分场合的硬性规定,我同意这是一个槽点。但如果不分场合地要求把所有属性 public 掉,也是不合适的。

  • Avalon   2013/08/13

    做任何事都要有个理由这一点,我已经被一朋友深刻吐槽了,他说我越学人变得越没意思,典型的工科生思维,我觉得这没有坏处。
    但是反过来说,其实有时候做事情不是刻意因为某个理由,其实也是让生活变得更有意思的一种方式吧。。

  • LesterYu   2013/08/13

    setters 和 getters 操作 肯定是有用的 可能确实你没用到吧,举个极端的例子吧 一个实体里有个日期字段 这个实体有好几个方法需要使用 需要格式为yyyy-mm-dd, 那么就在get方法里处理一下就行了 每个人就不需要在自己转类型了 或者说需要不同的格式 那么就可以加多个get方法。
    setters 和 getters 我没记错的话叫做构造方法吧。顾名思义了,嘿嘿
    一点浅见,如有不对之处,望包涵

  • 小侯yeah   2013/08/14

    关于单个返回语句,还有一个作为前提的最佳实践:单个方法和函数不应该写的太大。

    当方法不太大的时候单个返回语句很容易实现,并不像文中说的需要大量条件判断。当随着方法体的增长,虽然的确会出现文中提到的问题,但是,为什么要写一个大的方法呢?

    同时,当你有一个大的方法需要拆分时,如果这个方法有多个 return,重构就变得非常困难——当需要通过重构来拆分一个方法时,如果发现这个方法有多个返回语句,那么重构的第一步个就是把它变成一个单个返回语句的表达方式

    所以我觉得这个吐槽是不合理的,我仍然支持单个返回语句的最佳实践

    • Narcissu5   2013/08/15

      太多的短方法会造成调用栈过深,不仅影响性能,而且影响调试(想想一个异常几次rethrow)

      我觉得再大的方法,如果逻辑上是原子的都不应拆分。

  • 使用Setters/getters,禁止public属性
    ----------------------------------------------------------------
    不同意作者的观点。Setters/getters在你需要进行访问控制(例如只允许读不允许写)的时候会变得很有用,而这种情况经常发生。如果一开始直接声明为public成员,而后需要进行访问控制的时候,就需要花费大量的工作重构或者修改代码了。Setters/getters本身不会引入太多代码,但是却保证了访问安全,何乐而不为呢?
    我们往往不知道后期会做什么样的改动,所以提前给自己留条后路是明智的。

  • inkfish   2013/10/11

    import类而不是import包很有用。我是写Java的,以前接手一段遗留代码,里面基本都是import包,为了升级,踩了n个地雷,要是当初import类就不会这样了。

  • tanwan   2013/12/30

    在一个人单干看来你这些说的其实都不可以那么做...
    但是我觉得一个团队部分方法应该起码的吧?

跳到底部
返回顶部