[译] Java里臭名远扬的代码:你认出来了吗?

八月份的第三个周日,写的第四篇文章,坚持写下去一定会有收获,正所谓,万事开头难、中间难、结尾难。。。

okay,本周在实际工作中遇到了蛮多的新知识,鉴于每日工作繁忙,周日还要加班,因此只有周六一天可以‘忙中作乐’,不过这个周六依然过得十分‘充足’,上午陪同事找房子忙到下午2点,下午三点去学习游泳学到六点钟。此外,本周抽时间重新布局了我的卧室,安装了一张写字桌,组装一台电脑,现在终于可以在周日的晚上安安静静的写点东西。本周决定翻译一篇dzone.com上面的一篇文章练习一下,下周决定写一篇介绍 Android Notification 的文章,巩固学习。

阅读本文大概需要 4.5 分钟

正文

这些违反设计原则和质量的代码结构简直就是臭虫。

下面我们就列举一些常见的臭虫代码。

常量接口(Constant Interface)

常量接口只包含了静态常量数据成员,没有声明任何的方法在里面。建议的重构方式要根据常量接口里面常亮的种类:常量是类里面的成员可以被添加或者是可以被写入的枚举。接口 java.io.ObjectStreamConstant 就是一个很好的例子。

全局变量类(Global Variable Class)

这种类拥有一个公共静态成员(非final),由于这种变量可以被任何人修改,这就变成了类似于 C 语言里面的全局变量,不同的是,在使用前要加上类的名字来防止变量名冲突。下面是一个例子:

class Balls {    
    public static long balls = 0;
}

全局方法类 (Global Function Class)

这是一种只有一个静态公共方法没有任何其他的成员或者方法的public修饰的类;他有一个可选的用private属性修饰的构造方法来禁止实例化。这相当于C语言里面的全局函数,除了在使用他时需要在前面加上类的名字。

公共裸露的成员 (Publicly Exposed Fields)

这是一种public修饰的,他的成员都是public修饰的,非final,非static,并且没有任何方法在里面(可能会有一个可选的构造方法),这是难以保持的public修饰、类似C的一些类,正如 Effective Java 中所写道的:“一些java平台库里面的类,忽视public类不应该直接暴露成员的建议。最突出的例子就是 java.awt 包里面的 Point 类和 Dimension 类,这些栗子不是简单的来说说,而是应当被视作严重警示。

孤立的抽象(Orphan Abstract)

这是一个抽象abstract 修饰的没有任何实现类的类,一个抽象类,只有当具体实现的时候,他才能获得‘人生价值’。如果一个抽象类没有任何用处,那么还留你何用(可以移除了)?如果这个类可以考虑实例化,那么就去具体实现;如果这代表一种有用的抽象,就提供若干具体实现类去实现他。

被遗忘的接口 (Forgotten Interface)

一个类用同样的签名实现了所有接口列举的方法。这很有可能是一种失误:类原本是想要实现一个接口,但是忘记列举接口作为他的基本类型。这种臭虫做法的后果就是:该类的对象不能被视作接口的子类,于是,子类型的好处和运行多态都不能被利用。

双胞胎类 (Clone Class)

一个类完完全全克隆另外一个类,不是继承关系。实质上,只是类的名字不太一样,但是他们的全部成员、签名其他等等都是一样的。约束他们的仅仅是至少有一个不同的成员。一个例外就是那个成员顺序可能不太一样。
如果有若干个类拥有共同的成员或者表现,他们应该继承一个共同的类,包含那些共同的数据和表现。因此, 一个解决方法就是看看有没有可能提供一个基类,并且让其他类成为他的派生类 ,克隆类常常发生在复制粘贴代码,在这种情况下,最好就是移除副本,用一个独一无二的类取代。

孤独的类 (Lonely Class)

这种类不依赖于或使用任何其他类,并且,任何其他的类也不依赖或者使用这个类。这也许并不是一个错误或者失误,但是,然而,很少能见到一个非常独立的类和其他的类没有任何的联系。因此,我相信这应该是一个设计错误。

抽象类在不重要的位置(Abstract Leaf)

(这个实在不知道怎么翻译)抽象类在继承树的根部时一般都有很大的意义和用处,但是在另外一种情况下,当抽象类在继承树的叶子时:通常代表无意义可以被淘汰的;通常都意味着设计失误。

标记类 (Tagged Class)

这种情况通常发生在那些出身结构编程背景的程序员写的程序。他们通常像定义结构体一样定义类,而不是提供继承相关类型和多态。他们通常用一系列枚举和switch case 语句,或者是一串长长的 is else 语句 来区分类型然后做相应的操作。
术语 ‘tag class’ 来自于 Effective Java :“这种类的实例有两个或者更多的‘口味’ 并且有一个标签域指明这种实例的‘口味’”。
通过以为几点来检查是不是 ‘tag class’ :

  • 一个枚举(或者很多public 修饰的 static final 数据)来指出实例的flavour。
  • 一个域来保存 enum/int 的值,典型的,通常在构造函数中类设置他。
  • 一个switch语句在一个或者更多的方法里,基于tag来决定执行的代码。
    很明显的,重构 tag class 的方法就是继承。

小结

根据你的经验,你认出上面的那些代码了吗?欢迎补充更多的类似常见的代码。
有很多的静态分析工具(FindBugs, PMD, etc) 可以用来分析检查java里面的bug模式,然而,并没有很多的工具用于专门分析这样的臭代码。。希望未来能很快出现这样的分析工具。

作者有话说

还说啥。。。已经零点了,明天还得早起搬砖,晚安。
附上原文链接

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,761评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,953评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,998评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,248评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,130评论 4 356
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,145评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,550评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,236评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,510评论 1 291
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,601评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,376评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,247评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,613评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,911评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,191评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,532评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,739评论 2 335

推荐阅读更多精彩内容