是否有超缩进代码的替代方案?
我经常遇到必须执行大量检查的代码,并且在真正执行任何操作之前最终会缩进至少五到六级。 我想知道还有哪些替代方案。
下面我发布了一个我正在谈论的示例(这不是实际的生产代码,只是我突然想到的东西)。
public String myFunc(SomeClass input)
{
Object output = null;
if(input != null)
{
SomeClass2 obj2 = input.getSomeClass2();
if(obj2 != null)
{
SomeClass3 obj3 = obj2.getSomeClass3();
if(obj3 != null && !BAD_OBJECT.equals(obj3.getSomeProperty()))
{
SomeClass4 = obj3.getSomeClass4();
if(obj4 != null)
{
int myVal = obj4.getSomeValue();
if(BAD_VALUE != myVal)
{
String message = this.getMessage(myVal);
if(MIN_VALUE <= message.length() &&
message.length() <= MAX_VALUE)
{
//now actually do stuff!
message = result_of_stuff_actually_done;
}
}
}
}
}
}
return output;
}
I often run into code that has to perform lots of checks and ends up being indented at least five or six levels before really doing anything. I am wondering what alternatives exist.
Below I've posted an example of what I'm talking about (which isn't actual production code, just something I came up with off the top of my head).
public String myFunc(SomeClass input)
{
Object output = null;
if(input != null)
{
SomeClass2 obj2 = input.getSomeClass2();
if(obj2 != null)
{
SomeClass3 obj3 = obj2.getSomeClass3();
if(obj3 != null && !BAD_OBJECT.equals(obj3.getSomeProperty()))
{
SomeClass4 = obj3.getSomeClass4();
if(obj4 != null)
{
int myVal = obj4.getSomeValue();
if(BAD_VALUE != myVal)
{
String message = this.getMessage(myVal);
if(MIN_VALUE <= message.length() &&
message.length() <= MAX_VALUE)
{
//now actually do stuff!
message = result_of_stuff_actually_done;
}
}
}
}
}
}
return output;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
请参阅扁平化箭头代码获取帮助。
See Flattening Arrow Code for help.
提前返回:
Return early:
是的,还有另一种选择。
请永远不要编写这样的代码(除非您维护自己的代码)
我必须维护这样的代码,并且像 Charles_Bronsonn 电影一样糟糕(尽管有些人喜欢那些电影)
这种代码通常来自过程语言无论如何,比如 C (是 C 程序性的:P)。
这就是面向对象编程成为主流的原因。 它允许您创建对象并向它们添加状态。 使用该状态创建操作。 他们不仅仅是财产所有者。
我知道你编造了这个场景,但大多数时候所有这些条件都是业务规则!!。 大多数时候,这些规则会发生变化,如果原始开发人员不再存在(或者已经过去几个月),则不会有可行的方法来修改该代码。 规则读起来很困难。 很多痛苦都来自于此。
你能做什么?
1.) 使用私有成员变量(又称属性、属性、实例变量等)将对象的状态保留在对象内部。
2.) 将方法设为私有(这就是访问级别的用途)因此没有人会错误地调用它们并将程序放入 NullPointerException 区域。
3.) 创建定义条件的方法。 这就是他们所说的自记录代码
因此,我知道它看起来很冗长,而不是
创建一个方法
,但允许人们能够阅读代码。 编译器不关心可读性。
那么,使用这种方法进行超嵌套会是什么样子呢?
像这样。
我知道,看起来需要更多编码。 但想想这一点。 这些规则几乎是人类可读的
可能几乎可以读作
通过保持规则变化很小,编码人员可以很容易地理解它们,并且不用担心会破坏某些东西。
有关此内容的更多信息,请访问:http://www.refactoring.com/
Yes there is an alternative.
And please never code like that ( unless you're maintaining your own code )
I have had to maintain code like that and is as awful as a Charles_Bronsonn film ( some people like those films though )
This kind of code is usual comming from procedural languages such as C ( is C procedural :P ) Anyway.
That was the reason why ObjectOrientedProgrammng became mainstream. It allows you to create objects and add state to them. Create operations with that state. They're not only property holders.
I know you made up that scenario but most of the times all those conditions are business rules!!. Most of the times those rules CHANGE, and if the original developer is not longer there ( or a couple of months have already passed ) there won't be a feasible way to modify that code. The rules are awkward to read. And a lot of pain comes from that.
What can you do?
1.) Keep the state of the object INSIDE the object using private member variables ( AKA attributes, properties, instances vars etc. )
2.) Make the methods private ( that's what that access level is for ) so none can call them by mistake and put the program in the NullPointerException land.
3.) Create methods that define what the condition is. Thats what they call self documenting code
So instead of
Create a method
I know it looks verbose, but allows human be able to read the code. The compiler does not care about readability.
So how would it look like your hypernested with this approach?
Like this.
I know, It looks like more coding. But think about this. The rules are almost human readable
May be almost read as
And by keeping the rules vary small, the coder may understand them very easily and not be afraid of brake something.
A lot more can be read about this at: http://www.refactoring.com/
是的,您可以按如下方式删除缩进:
基本上按顺序进行检查,并与失败而不是成功进行比较。
它消除了嵌套并使其更易于遵循(IMO)。
Yes, you could remove the indents as follows:
Basically do the checks sequentially, and compare against failure rather than success.
It removes the nesting and makes it easier to follow (IMO).
如果不需要处理停止,则不要嵌入。
例如,您可以这样做:
假设您使用的是 Java 等对条件进行排序的语言。
或者,您可以:
对于更复杂的情况。
这个想法是,如果不需要处理,则从该方法返回。 嵌入大型嵌套 if 几乎无法读取。
If you don't need to process stop, don't embed.
For example, you can do:
Assuming you're using a language like Java that orders the conditionals.
Alternatively you could:
For more complex cases.
The idea is to return from the method if you don't need to process. Embedding in a large nested if is almost impossible to read.
您可以使用保护子句来消除一些嵌套。
不过,将我用来说明这一点的所有
return "";
语句更改为抛出各种描述性异常的语句。You can get rid of some of the nesting by using guard clauses.
Change all of the
return "";
statements that I used to illustrate the point to statements that throw a descriptive variety of Exception, though.如果这只是一个可读性问题,您可以通过将嵌套移至另一种方法来使其更清晰。 如果您愿意,还可以转换为后卫风格。
if it's just a readability issue you could make it clearer by moving the nesting to another method. Additionally convert to guard style if you like.