java 是否有太多嵌入式 if 语句?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6536074/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 16:14:52  来源:igfitidea点击:

Is there such a thing as too many embedded if-statements?

javacoding-styleif-statement

提问by Cody

Currently I am working on a bit of code which (I believe) requires quite a few embedded if statements. Is there some standard to how many if statements to embed? Most of my googling has turned up things dealing with excel..don't know why.

目前我正在编写一些代码(我相信)需要相当多的嵌入式 if 语句。有多少 if 语句要嵌入的标准?我的大部分谷歌搜索都发现了处理 excel 的事情......不知道为什么。

If there is a standard, why? Is it for readability or is it to keep code running more smoothly? In my mind, it makes sense that it would be mainly for readability.

如果有标准,为什么?是为了可读性还是为了让代码运行更顺畅?在我看来,它主要是为了可读性是有道理的。

An example of my if-structure:

我的 if 结构的一个例子:

if (!all_fields_are_empty):
    if (id_search() && validId()):
        // do stuff
    else if (name_search):
        if (name_exists):
            if (match < 1):
                // do stuff
        else:
            // do stuff
    else if (name_search_type_2):
        if (exists):
            if (match < 1):
                // do stuff
        else:
            // do stuff
else:
    // you're stupid

I have heard that there's a limit to 2-3 nested for/while loops, but is there some standard for if-statements?

我听说有 2-3 个嵌套的 for/while 循环的限制,但是 if 语句有一些标准吗?

Update:I have some years under my belt now. Please don't use this many ifstatements. If you need this many, your design is probably bad. Today, I LOVE when I can find an elegant way to do these things with minimal ifstatements or switchcases. The code ends up cleaner, easier to test, and easier to maintain. Normally.

更新:我现在有几年的时间了。请不要使用这么多if语句。如果你需要这么多,你的设计可能很糟糕。今天,我喜欢用最少的if语句或switch案例找到一种优雅的方式来做这些事情。代码最终变得更清晰、更易于测试且更易于维护。一般。

采纳答案by Randy

Technically, I am not aware of any limitation to nesting.

从技术上讲,我不知道嵌套有任何限制。

It might be an indicator of poor design if you find yourself going very deep.

如果你发现自己走得很深,这可能是糟糕设计的一个指标。

Some of what you posted looks like it may be better served as a casestatement.

您发布的某些内容看起来可能更适合作为case声明使用。

I would be concerned with readability, and code maintenance for the next person which really means it will be difficult - even for the first person (you) - to get it all right in the first place.

我会担心下一个人的可读性和代码维护,这真的意味着很难 - 即使对于第一个人(你) - 一开始就把它做好。

edit:

编辑:

You may also consider having a class that is something like SearchableObject(). You could make a base class of this with common functionality, then inherit for ID, Name, etc, and this top level control block would be drastically simplified.

您也可以考虑拥有一个类似于SearchableObject(). 你可以创建一个具有通用功能的基类,然后继承 ID、名称等,并且这个顶级控制块将被大大简化。

回答by bezmax

As Randy mentioned, the cause of this kind of code is in most cases a poor design of an application. Usually I try to use "processor" classes in your case.

正如 Randy 提到的,这种代码的原因在大多数情况下是应用程序设计不佳。通常我会尝试在您的情况下使用“处理器”类。

For example, given that there is some generic parameter named "operation" and 30 different operations with different parameters, you could make an interface:

例如,假设有一些名为“操作”的通用参数和具有不同参数的 30 个不同操作,您可以创建一个接口:

interface OperationProcessor {
   boolean validate(Map<String, Object> parameters);
   boolean process(Map<String, Object> parameters);
}

Then implement lots of processors for each operation you need, for example:

然后为您需要的每个操作实现大量处理器,例如:

class PrinterProcessor implements OperationProcessor {
    boolean validate(Map<String, Object> parameters) {
       return (parameters.get("outputString") != null);
    }
    boolean process(Map<String, Object> parameters) {
       System.out.println(parameters.get("outputString"));
    }
}

Next step - you register all your processors in some array when application is initialized:

下一步 - 在应用程序初始化时将所有处理器注册到某个数组中:

public void init() {
    this.processors = new HashMap<String, OperationProcessor>();
    this.processors.put("print",new PrinterProcessor());
    this.processors.put("name_search", new NameSearchProcessor());
    ....
}

So your main method becomes something like this:

所以你的主要方法变成了这样:

String operation = parameters.get("operation"); //For example it could be 'name_search'
OperationProcessor processor = this.processors.get(operation);
if (processor != null && processor.validate()) { //Such operation is registered, and it validated all parameters as appropriate
   processor.process();
} else {
   System.out.println("You are dumb");
}

Sure, this is just an example, and your project would require a bit different approach, but I guess it could be similiar to what I described.

当然,这只是一个例子,您的项目需要一些不同的方法,但我想它可能与我描述的相似。

回答by Michael J. Lee

I don't think there is a limit but i wouldn't recommend embeddeding more the two - it's too hard to read, difficult to debug and hard to unit test. Consider taking a look at a couple great books like Refactoring, Design Patterns, and maybe Clean Code

我不认为有限制,但我不建议嵌入更多的两个 - 它太难阅读,难以调试和难以单元测试。考虑看看几本好书,比如重构设计模式,也许还有干净的代码

回答by DoctorMick

Technically you can have as many as you like but if you have a lot it can quickly make the code unreadable.

从技术上讲,您可以拥有任意数量的代码,但如果您拥有大量代码,它很快就会使代码变得不可读。

What i'd normally do is something like:

我通常会做的是:

if(all_fields_are_empty) {
    abuseuser;
    return;
}

if(id_search() && validId()) {
  //do stuff
  return;
}

if(name_search)
{
  if(name_exists)
    //do stuff
    return
  else
    //do stuff
    return
}

I'm sure you get the picture

我确定你看懂了

回答by Liam

Tl;DrYou don't really want anymore than 10-15 paths though any one method

Tl;Dr你真的不想要超过 10-15 条路径,尽管任何一种方法

What your essentially referring to here is Cyclomatic complexity.

您在这里主要指的是Cyclomatic complex

Cyclomatic complexity is a software metric (measurement), used to indicate the complexity of a program. It is a quantitative measure of the number of linearly independent paths through a program's source code. It was developed by Thomas J. McCabe, Sr. in 1976.

圈复杂度是一种软件度量(measurement),用于表示程序的复杂度。它是通过程序源代码的线性独立路径数量的定量度量。它由 Thomas J. McCabe, Sr. 于 1976 年开发。

So every if statement is potentially a new path though your code and increases it's Cyclomatic complexity. There are tools that will measure this for you and high light areas of high complexity for potential refactoring.

因此,每个 if 语句都可能是您代码中的一条新路径,并增加了它的圈复杂度。有一些工具可以为您测量这一点,并为潜在的重构提供高复杂度的高亮区域。

Is there some standard to how many if statements to embed?

有多少 if 语句要嵌入的标准?

Yes and no. It's generally regarded (and McCabe himself argued) that a Cyclomatic complexity of over about 10 or 15 is too highand a sign that the code should be refactored.

是和否。人们普遍认为(并且 McCabe 本人认为)超过大约 10 或 15圈复杂度太高了,这表明代码应该重构。

One of McCabe's original applications was to limit the complexity of routines during program development; he recommended that programmers should count the complexity of the modules they are developing, and split them into smaller modules whenever the cyclomatic complexity of the module exceeded 10.[2] This practice was adopted by the NIST Structured Testing methodology, with an observation that since McCabe's original publication, the figure of 10 had received substantial corroborating evidence, but that in some circumstances it may be appropriate to relax the restriction and permit modules with a complexity as high as 15. As the methodology acknowledged that there were occasional reasons for going beyond the agreed-upon limit, it phrased its recommendation as: "For each module, either limit cyclomatic complexity to [the agreed-upon limit] or provide a written explanation of why the limit was exceeded."[7]

McCabe 最初的应用之一是在程序开发过程中限制例程的复杂性;他建议程序员应该计算他们正在开发的模块的复杂度,并在模块的圈复杂度超过 10 时将它们拆分为更小的模块。 [2] 这种做法被 NIST 结构化测试方法采用,观察到自 McCabe 的原始出版物以来,10 的数字已收到大量确凿的证据,但在某些情况下,放宽限制并允许具有复杂性的模块可能是合适的,如高达 15。由于该方法承认偶尔有超出商定限制的原因,因此将其建议表述为:“对于每个模块,

This isn't really a hard rule though and can be disregarded in some circumstances. See this question What is the highest Cyclomatic Complexity of any function you maintain? And how would you go about refactoring it?.

不过,这并不是真正的硬性规则,在某些情况下可以忽略。请参阅此问题您维护的任何函数的最高圈复杂度是多少?你将如何重构它?.

why? Is it for readability or is it to keep code running more smoothly?

为什么?是为了可读性还是为了让代码运行更顺畅?

Essentially this is for readability, which should make your code run smoothly. To quote Martin Fowler

本质上这是为了可读性,这应该使您的代码运行顺畅。引用马丁福勒的话

Any fool can write code that a computer can understand. Good programmers write code that humans can understand.

任何傻瓜都可以编写计算机可以理解的代码。优秀的程序员会编写人类可以理解的代码。

回答by nfechner

The only technical limit to the number of nested if/else blocks in Java will probably be the size of your stack. Style is another matter.

Java 中嵌套 if/else 块数量的唯一技术限制可能是堆栈的大小。风格是另一回事。

Btw: What's with the colons?

顺便说一句:冒号是怎么回事?