读书人

“恶心代码”帖子中的一个回复,该怎么

发布时间: 2012-03-21 13:33:15 作者: rapoo

“恶心代码”帖子中的一个回复
曾在一个帖子中回复过最恶心的代码,摘抄如下:

Java code
public void process(File file) {    if (file != null) {        if (file.exists()) {            if (!file.isDirectory()) {                if (file.canRead()) {                    // do something;                }            }        }    }}


详见下面这个帖子 23 楼的回复:

你见过最恶心的代码是什么样子的?
http://topic.csdn.net/u/20111020/16/e04cf593-4789-418b-8142-88c231002402.html

本来准备睡觉的,刚才翻了一下这个帖子,得,没法睡了,得发帖子了!

打 23 楼后,回复的同学竟然都异口同声地表明这代码没有问题!

我一直告诫组员,代码中的 for、if 的嵌套不应该超过两层,超过的话得想办法重构。从那个帖子的回复来看,难道是我错了?抑或是我太敏感,还是这个代码真的没有问题?

纯技术帖,谢绝“顶”、“Mark”之类无意义的回复,谢谢配合!

[解决办法]
当初老师教的也是这么说的 for if 循环嵌套不要超过2到3层
有代码执行效率方面和阅读代码方便的考虑吧
以后继续保持
[解决办法]
确实有些隐患,一些特殊情况下不执行任何代码就跳过了,在后继的代码中不好界定处于什么状态
[解决办法]
Java code
import com.google.common.base.Preconditions.checkNotNull;public void process(File file){    checkNotNull(file);    if(file.isFile() && file.canRead(){        ...    }}
[解决办法]
探讨
确实有些隐患,一些特殊情况下不执行任何代码就跳过了,在后继的代码中不好界定处于什么状态

[解决办法]
checkNotNull很多开源项目的做法是Assert.notNull(file,"参数不能为空");

很多项目中都有自己的Assert类


探讨

Java code
import com.google.common.base.Preconditions.checkNotNull;
public void process(File file){
checkNotNull(file);
if(file.isFile() && file.canRead(){
...
}
}

[解决办法]
是啊!!是初学者
[解决办法]
重构太多会导致混乱的,楼主不要使用这么多嵌套
[解决办法]
使用太多的嵌套是不好 但是有时候需要多层嵌套解决问题更加容易
[解决办法]
嵌套太多了,肯定要重构。
[解决办法]
支持楼主~~
[解决办法]
代码中的 for、if 的嵌套三四层应该是可以接受的吧
只是可以接受,尽量不要这样写就好了
[解决办法]
Java code
//一般我喜欢这么做public void process(File file) {        if (file == null)return;        if(!file.exists())return;        if(file.isDirectory())return;        if(!file.canRead())return;        .....        doSomething        .....    }
[解决办法]
嵌套太多不好
[解决办法]
怎么重构啊?给个例子,莫非就是把几个if弄到一块,弄个&&吗?
探讨
引用:
确实有些隐患,一些特殊情况下不执行任何代码就跳过了,在后继的代码中不好界定处于什么状态

超过的话得想办法重构,怎么重构法?谢谢

[解决办法]
com.google.common.base.Preconditions.checkNotNull
这个类原来是androidSDK里的啊,终于找到了,谢谢,又开眼界了
[解决办法]
大家不要把新手当老手看,他们考虑问题的时候跟我们想的不一样;大家刚出来的时候未必就没写过恶心代码,随着经验的增长,再看以前写的代码,总觉得以前自己好白痴。
------解决方案--------------------


哈哈~如果只在最里面的一层写 处理代码,感觉还可以啊~
如果每层if 都有不同处理话~那就要恶心死了~ 12L的 方法挺有意思的,可以借鉴啊~


[解决办法]

探讨

com.google.common.base.Preconditions.checkNotNull
这个类原来是androidSDK里的啊,终于找到了,谢谢,又开眼界了

[解决办法]
一声叹息
[解决办法]
其实嵌套几层这个我觉得没什么硬性规定 虽然我也不喜欢嵌套很多层(最近正在用while和break将原本的嵌套给展开) 可有些时候这样写是必要的 比如上面的代码在不满足条件的时候要进行一些处理 而满足条件还要做其他验证的情况下 就要这么做

不过这段代码倒是没必要 因为咋看他都可以写到一个IF里去..
[解决办法]
用断言 学习了
[解决办法]
我也有这样的逻辑,随着学习的深入,以后可能会改进吧。。。虽然也知道这样写太“恶心”。。
[解决办法]
还是要注意代码规范,以后得要多看看好的代码
[解决办法]
嗯,嵌套少一点看上去优雅一点
[解决办法]
代码很严谨,表述很清晰,不是吗? 几层真的是一个绝对的指标吗?

清晰和严谨才是写代码的宗旨,至于几层,什么的,那些事具体的实现方式,方式不能太死板了。


[解决办法]
使用swich case.....
[解决办法]
探讨

Java code

//一般我喜欢这么做
public void process(File file) {
if (file == null)return;
if(!file.exists())return;
if(file.isDirectory())return;
if(!file.canRead())return;
……

[解决办法]
Java code
if (file != null && file.exists() && !file.isDirectory() && file.canRead())
[解决办法]
探讨

Java code

if (file != null && file.exists() && !file.isDirectory() && file.canRead())

[解决办法]
我想知道,还有哪些更好的解决之道呢。


我也常写LZ这样的烂代码。
[解决办法]
也许写的时候觉得可以理解,但后面绝对会疑惑自己为什么这样写
[解决办法]
我个人感觉if嵌套太多层了,12L的写法比较正常
[解决办法]
帮忙顶一下。
[解决办法]
在性能一样的情况下,当然选择可读性高的表现方式了!
如果我的话,选下面这种写法:
Java code
public void process(File file) {    if (file != null && file.exists() && !file.isDirectory() && file.canRead()){       // do something;    }}
[解决办法]
一般null和""放一个条件里。
其他都是
if(xxx)xxxx;
if(xxx)xxxx;
if(xxx)xxxx;
if(xxx)xxxx;
...
[解决办法]
这个确实比较恶心,但这决不是我见过最恶心的,至少看代码就知道程序员写来干啥的,逻辑性差点,但至少可阅读。


[解决办法]
有所收获哦。。
[解决办法]
看了上面的说的方法,大概有两种,
1. if()return;
2. if(。。。。。)所有条件&&到一起。
针对上面这个问题,用1比2更好些,至少我不太喜欢看太长的语句。



同样期待楼主给出更好的方法。。。。。。

[解决办法]
期待LZ的方法...
[解决办法]

探讨
看了上面的说的方法,大概有两种,
1. if()return;
2. if(。。。。。)所有条件&&到一起。
针对上面这个问题,用1比2更好些,至少我不太喜欢看太长的语句。

同样期待楼主给出更好的方法。。。。。。

[解决办法]
探讨
引用:

引用:

Java code

//一般我喜欢这么做
public void process(File file) {
if (file == null)return;
if(!file.exists())return;
if(file.isDirectory())return;
……

[解决办法]
一声叹息。

与我一样的小小菜鸟,须多磨练、磨练!!!!!!!!!!!!!!!!!
[解决办法]
能少嵌套一些固然是好,可是有时候的逻辑还是需要多重判断

代码审核吧,我有时没事了就喜欢拿自己以前写的代码来审核,虽然很多时候对自己写的不是容易就检测出问题,但是有时还是可以发现存在许多的问题,对规范啊什么的都有好处
[解决办法]
楼主如何去检查这些提交的代码,检查成千上万的代码是否符合那些“规范”?
换一种思路,你就不会认为这样的代码有何不妥:
1.已通过测试作为提交工单的标准;(而不是代码是否“漂亮”);
2.程序员追求的是用最快的速度通过测试,这样单位时间他们可以去领更多的工单;
3.给没有足够经验的程序员一些建议,帮助他们少走一些弯路;

[解决办法]
探讨
引用:

Java code

if (file != null && file.exists() && !file.isDirectory() && file.canRead())

我很难在10秒钟内读懂

[解决办法]
探讨
引用:

Java code

if (file != null && file.exists() && !file.isDirectory() && file.canRead())

我很难在10秒钟内读懂

[解决办法]
起码人家还知道缩进呢
[解决办法]
探讨
Java code


//一般我喜欢这么做
public void process(File file) {
if (file == null)return;
if(!file.exists())return;
if(file.isDirectory())return;
if(!file.canRead())retu……

[解决办法]
探讨
Java code


//一般我喜欢这么做
public void process(File file) {
if (file == null)return;
if(!file.exists())return;
if(file.isDirectory())return;
if(!file.canRead())retu……

[解决办法]
三种代码写法的比较:
代码:
Java code
public class Test6 {    public static void main(String[] args) {        test1();        test2();        test3();    }    static void test1() {        int t = 10;        if (t > 0)            if (t < 20)                if (t != 15)                    System.out.println(100);    }    static void test2() {        int t = 10;        if (t <= 0)            return;        if (t >= 20)            return;        if (t == 15)            return;        System.out.println(100);    }    static void test3() {        int t = 10;        if (t > 0 && t < 20 && t != 15)            System.out.println(100);    }}
[解决办法]

条件合并就可以了??
------解决方案--------------------


有时候程序判断出结果, 并不就是要 return.
我的写法如下:

void funtcion()
{
do {
if (expression1)
break;
if (expression2)
break;
if (expression2)
break;
// do something;
} while(false);
}
[解决办法]
我感觉用&&运算进行合并 应该可以吧
[解决办法]
这真的很恶心,一般不要超过两层,支持lz

[解决办法]
觉得用return那个比较好
[解决办法]
我感觉这点效率在java里,真就无所谓。

探讨
三种代码写法的比较:
代码:

Java code


public class Test6 {
public static void main(String[] args) {
test1();
test2();
test3();
}

static void test1() {
……

[解决办法]
人才

[解决办法]
接手的人总觉得之前的人是SB
唉.....
[解决办法]
这样的写法,只能说明coder心思细腻,稳重,小心谨慎
[解决办法]
唉,觉得恶心的帮忙修改一下成不恶心的。

一般恶心的代码都是夹杂着业务逻辑的,修改别人的代码又不知道业务逻辑重构个屁。
[解决办法]
就是你太敏感了。
我见过最恶心的是这样的:
String s1,s2,s3,s4,s5;
(所有的变量名都是这样,方名就是m1,m2,m3,m4)
然后下面外加3000行业务处理罗辑。
恶心吧。我足足搞了三天才帮这东西除完所有的BUG。外加改了一下功能,这完全草泥马。。
[解决办法]
我改正常一点的代码,加一点小功能,连读带改一般就一天。。
不能接受别人代码,不能从代码中看出业务逻辑的,那还是不是很及格。
当然,像我上面说的那种,不知道是故意还是傻~Q@!#$!@#$#@%的行为除外。
[解决办法]
探讨
曾在一个帖子中回复过最恶心的代码,摘抄如下:

Java code
public void process(File file) {
if (file != null) {
if (file.exists()) {
if (!file.isDirectory()) {
if (file.canRead()) {
……

[解决办法]
能实现功能就行了,哪儿来的那么多讲究!!!
[解决办法]
楼主,你可以说一个人长得丑,但是随便骂一个人长的恶心就不厚道了
[解决办法]
额,最多写过五重的for循环,当时是公司考试,没时间考虑算法,我们项目经理给的评价是“很清晰的死磕”。
LZ的情况,我大都都是 IF(XX==XX)return;....
[解决办法]
探讨
楼主如何去检查这些提交的代码,检查成千上万的代码是否符合那些“规范”?
换一种思路,你就不会认为这样的代码有何不妥:
1.已通过测试作为提交工单的标准;(而不是代码是否“漂亮”);
2.程序员追求的是用最快的速度通过测试,这样单位时间他们可以去领更多的工单;
3.给没有足够经验的程序员一些建议,帮助他们少走一些弯路;

[解决办法]
探讨
楼主怕的是后期维护,不是好看不好看,能过固然就可以了,后期谁维护代码谁倒霉

[解决办法]
有很多问题确实应该注意
[解决办法]
动不动就以“恶心”来评价代码的人,多多少少有点自以为是或者自恋。这段代码其实没有什么问题,条件合并或提炼成一个判断方法的做法有时候更加让人受不了。
[解决办法]
其实 很多后期维护都是别人来做的 o(∩_∩)o 哈哈 所以随便写 。。。

至于比较好的写法如下

if(a)
return;
if(b)
return;
if(c)
return;
if(d)


{
do something...
}

这个框架原来里面大部分是这种写法。
[解决办法]
我觉得你主楼贴的代码逻辑比12楼31楼的方法清晰。
因为这段代码是层层递进关系,所以用if嵌套比一堆return或一个if清晰。
[解决办法]
我见过的最恶心的代码是这这样的:
void func1()
{
func2();
}

void func2()
{
func3();
}

void func3()
{
func4();
}

继续N层......
[解决办法]
这位同学很有才啊

探讨
楼主,你可以说一个人长得丑,但是随便骂一个人长的恶心就不厚道了

[解决办法]
呵呵,凑个热闹,贴个C#的Code
C# code
public void process(string filePath) {    if(string.IsNullOrEmpty(filePath))    {         return;    }        if(File.Exist(filePath))    {        try        {            File file = new File(filePath);            //do something        }        catch        {            return;        }    }}
[解决办法]
各种写法前面已经写的差不多了,
我的疑惑是为什么这个方法要这么多前置判断,之前调用它的逻辑难道一点合法判断都没做吗?
[解决办法]
错了,修改一下

C# code
public void process(string filePath) {    if(string.IsNullOrEmpty(filePath))    {         return;    }        if(File.Exist(filePath))    {        try        {            //do something        }        catch        {            return;        }    }}
[解决办法]
探讨
引用:

...

我很难在10秒钟内读懂

[解决办法]
无聊一下, 重构代码,太佩服我自己了

static bool Check_file_readable(File *file)
{

if (file == null && !file.exists()) {
return false;
}
if (file_isDirectory) {
return false;
}

return file.canRead();
}

public void process(File *file) {

if (check_file_readable(file)) {
// do something;
}
[解决办法]
探讨

引用:
引用:

...

我很难在10秒钟内读懂

Yup.这个示例 楼主说的“恶心”写法更清晰

面向对象编程是很强调 可读性 和 可维护性。

个人倾向于提炼方法的做法(放哪里你知道的):
Java code

public void process(File file) {
……

[解决办法]
先不说这个代码是不是恶心,关键是如果让第二个人接手的话,可真看不明白!我还是感觉12楼的代码清楚,效率的话暂时不在考虑范围之内!
[解决办法]
我觉得83 84楼是最佳解决方案, 性能的问题就不要放在这里扯了,一个函数嵌套死不了人
[解决办法]
Java code
public void process(File file) {  try{     //do something   }catch(Exception){}}
[解决办法]
你们在搞艺术吗?
[解决办法]
给力哇~
探讨
三种代码写法的比较:
代码:

Java code


public class Test6 {
public static void main(String[] args) {
test1();
test2();
test3();
}

static void test1() {
……

[解决办法]
哇塞,了解了,原来那叫防御式编程,又多了一招。


[解决办法]
我记得重构还是那本上说过,如果有多个if返回的结果都是一样的,那就把他们放在一起用&&或||运算符,因为多一个if,也就意味着多一种分支,多一种情况
[解决办法]
要一正,程要。
[解决办法]
感觉只有一个问题,
只处理了if
没有处理else

至于,2层、3层,没有必要太教条
[解决办法]

探讨

Java code

//一般我喜欢这么做
public void process(File file) {
if (file == null)return;
if(!file.exists())return;
if(file.isDirectory())return;
if(!file.canRead())return;
……

[解决办法]
在《重构》里好像看过这样的处理方法,原来叫防御式编程。
探讨

Java code

//一般我喜欢这么做
public void process(File file) {
if (file == null)return;
if(!file.exists())return;
if(file.isDirectory())return;
if(!file.canRead())return;
……

[解决办法]
探讨
但是,我好像记得有人提过:一个函数里面最好只有一个return

[解决办法]
所谓的程序要有一个入口,一个出口。其实不必拘泥于教条,多个return也是没什么问题的。
探讨

引用:

Java code

//一般我喜欢这么做
public void process(File file) {
if (file == null)return;
if(!file.exists())return;
if(file.isDirectory())return;
if(!file.canRead())return……

[解决办法]
大学里有一个理论,结构化程序设计,就是一个函数应该只有一个入口和一个出口。但是就我们程序员来讲,这属于纸上谈兵,把这交给理论家玩蛋去吧!
[解决办法]
我也不喜欢,但是我一眼能看懂,这就算正常。

读书人网 >J2SE开发

热点推荐