是否存在嵌入太多 if 语句的情况?

发布于 2024-11-18 01:04:50 字数 861 浏览 6 评论 0原文

目前我正在编写一些代码(我相信)需要相当多的嵌入式 if 语句。嵌入多少 if 语句是否有一些标准?我的大部分谷歌搜索都发现了与 Excel 相关的内容……不知道为什么。

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

我的 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

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

更新: 我现在已经有几年了。请不要使用这么多 if 语句。如果您需要这么多,那么您的设计可能很糟糕。今天,我喜欢找到一种优雅的方式来用最少的 if 语句或 switch 案例来完成这些事情。代码最终变得更干净、更容易测试、更容易维护。通常情况下。

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 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 (!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?

Update:
I have some years under my belt now. Please don't use this many if statements. 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 if statements or switch cases. The code ends up cleaner, easier to test, and easier to maintain. Normally.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

甜柠檬 2024-11-25 01:04:50

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

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

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

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

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"));
    }
}

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

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

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

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");
}

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

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.

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

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.

私藏温柔 2024-11-25 01:04:50

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

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

迷路的信 2024-11-25 01:04:50

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

如果你发现自己走得很深,这可能表明设计很糟糕。

您发布的一些内容看起来可能更适合用作 case 语句。

我会关心下一个人的可读性和代码维护,这实际上意味着即使对于第一个人(你)来说,一开始就很难把事情做好。

编辑:

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

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 case statement.

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.

等风来 2024-11-25 01:04:50

Tl;Dr 通过任何一种方法,您实际上并不需要超过 10-15 条路径,

您在这里实质上指的是 环复杂度

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

因此,每个 if 语句都可能成为代码中的一条新路径,并增加其循环复杂性。有一些工具可以为您测量这一点,并突出显示高复杂性的区域以进​​行潜在的重构。

对于要嵌入的 if 语句数量是否有一些标准?

是的,也不是。人们普遍认为(McCabe 本人也认为)超过 10 或 15 的循环复杂度就太高了,这表明代码应该重构。

McCabe 最初的应用之一是限制
程序开发期间的例程;他建议程序员
应该计算他们正在开发的模块的复杂性,并且
每当圈复杂度达到时,将它们分成更小的模块
模块超过10个。[2]这种做法被 NIST 采用
结构化测试方法,观察到自从
McCabe 的原始出版物,数字 10 已收到
大量确凿的证据,但在某些情况下
可能适当放宽限制并允许模块
复杂性高达 15。该方法论承认,
偶尔有超出商定限度的原因,
其建议措辞如下:“对于每个模块,要么限制
圈复杂度达到[商定的限制]或提供书面
解释为什么超出限制。”[7]

但这并不是一个真正的硬性规则,在某些情况下可以忽略。请参阅这个问题 您维护的任何函数的最高循环复杂度是多少?您将如何进行重构是吗?

为什么?是为了可读性还是为了让代码更多地运行
顺利吗?

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

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

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

What your essentially referring to here is Cyclomatic complexity.

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.

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.

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

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

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]

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.

嗼ふ静 2024-11-25 01:04:50

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

我通常会做这样的事情:

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
}

我相信你明白了

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

久光 2024-11-25 01:04:50

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

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

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.

Btw: What's with the colons?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文