6

当我第一次开始编程时,我把所有东西都写在 main.js 中。main()但据我所知,我试图在我的方法中尽可能少做。

但是你决定让其他类/方法负责从哪里接管程序main()?你怎么做呢?

我见过很多方法,比如:

class Main
{
  public static void main(String[] args)
  {
    new Main();
  }
}

有些像:

class Main {

   public static void main(String[] args) {

    GetOpt.parse(args);

    // Decide what to do based on the arguments passed
    Database.initialize();
    MyAwesomeLogicManager.initialize();
    // And main waits for all others to end or shutdown signal to kill all threads.
  }
}

应该做什么和不应该做什么main()?还是没有银弹?

谢谢你的时间!

4

8 回答 8

17

主函数中的代码:

  • 不能进行单元测试。
  • 无法通过注入接收依赖项。
  • 不能被类似于您编写的第一个应用程序的其他应用程序重用。

因此 main 函数中的代码:

  • 必须非常简单,以至于您只对功能/系统测试感到满意。
  • 必须负责为所有其他代码使用的依赖项设置滚动(也就是说,main 就像创建应用程序的超级工厂一样)。
  • 应该只做特定于你的应用程序设置方式的事情(即测试代码或演示版本不需要做完全相同的事情)。

在实践中,这意味着真正的应用程序没有太多的主要内容。玩具应用程序和一次性程序可能有很多主要内容,因为您不打算测试或重用它们。

实际上,我上面所说的一些内容是特定于 C++ 的。Java 主要方法当然可以由测试代码或变体应用程序调用。但是它们仍然不将对象作为参数,仅将命令行参数作为参数,因此它们在测试中被隔离或在重用方面表现良好的程度非常低。我想你可以传递类名让它们实例化并用于创建应用程序的其余部分。

[编辑:有人从这个问题中删除了“C++,Java”标签。所以:我上面说的是 C++ 和 Java 特定的。其他语言可能以不那么特殊的方式对待 main ,在这种情况下,您也可能没有特别的理由来特殊对待它。]

于 2008-11-28T12:25:57.133 回答
7

在我看来,一个大型项目的“主要”应该包含大约 3 个函数调用:

  • 调用为应用程序设置所有必需设置、首选项等的初始化函数。
  • 启动应用程序的主“控制器”
  • 等待主控制器终止,然后调用 Termination 函数来清理“main”中需要清理的任何内容(尽管控制器已经完成了大部分清理工作)。

任何相当大的应用程序都会被分成功能块,通常具有一些层次结构。主控制器可能有几个用于特定功能的子控制器。

这样做可以更容易地找到特定的功能,并且更好地分离关注点。

当然,正如其他回复所说,软件开发确实没有灵丹妙药。对于一个简短的项目,我可能会将所有内容都放在 main 中,以便快速启动和运行。我认为还取决于语言 - 某些选项可能比特定语言中的其他选项更容易。

于 2008-11-28T10:46:13.117 回答
4

正如他们所说,无论你的船漂浮着什么。:) 你应该真正专注于使代码简单、易于阅读和高效,使用你需要的任何工具来实现这一点。如果它保证在 main 中放置大量代码 - 就这样做。如果你觉得物品会让事情更有条理——那就去吧。

制作单个实例class Main然后调用Main()完成所有工作的实例方法与直接在 main 方法中编写所有内容一样好。

于 2008-11-28T10:41:36.607 回答
2

我会说这不是你的主要功能,但不是。根据项目的复杂程度,您需要将其分解为功能部分,例如“数据库功能”、“显示功能”、“与牧师一起喝下午茶”等。

这都是关于代码的可读性。以前从未见过您的程序的其他人能否在遇到它时首先对它的作用有一个很好的概括性想法?

然后可以很容易地看到该去哪里更深入地挖掘机制?

您使用的每个功能部分是否仅执行逻辑流程块?它不必只做一件事,但它不应该做所有事情加上厨房水槽。

以一种外部资源可维护的方式分解您的代码。

因为老天知道,当涉及到它时,如果有人 - 其他 - 可以修复这个错误,那就更好了 =)

作为对您问题的直接回答,我会将对每个主要组件的函数调用放在 main、设置、过程和完成中,以便查看它的任何人都能快速了解程序的工作原理。然后,如果需要,他们可以进一步深入研究。

于 2008-11-28T10:55:58.307 回答
2

看,“main”方法的内容和形式非常依赖于语言和环境。在 Java 中,每个类都可以有一个public static void main()方法,因此拥有多个方法是完全可行的。

但是现在,让我们通过帕纳斯模块化定律来思考这个问题:“每个模块都隐藏着一个秘密,而这个秘密是可以改变的。” 最初调用的模块的“秘密”是进程与操作系统接口的细节:诸如获取参数和处理不规则终止之类的事情。在 Python 中,这会导致如下情况:

def main(args=None):
    #argument processing
    #construct instances of your top level objects
    #do stuff

if __name__ == "__main__":
   try:
      main(Sys.Argv)
   except: # everything
      # clean up as much as you can
   else:
      # normal cleanup, no exceptions

这里的重点是您可以从环境中获取所有内容,然后调用 main() 函数;您捕获所有未捕获的异常,并在程序终止之前对它们进行智能处理。

于 2008-12-08T02:08:32.987 回答
0

我认为主要方法应该解释程序在启动时的作用。所以它可能会调用初始化方法,但应该将逻辑提取到方法中。

在您的示例中,我不会创建 Main() 方法,而是将其放入原始方法中。

于 2008-11-28T10:38:37.517 回答
0

你的程序设计将决定你的“主要”的形状。

有一个“规则”来说明你的主要功能应该是什么 - 恕我直言 - 胡说八道。

于 2008-11-28T10:55:51.693 回答
0

请记住,如果有人想了解您的程序是如何工作的,他们可能首先要看的地方是 main(至少我会)。所以,我认为尽可能少地投入它不是一个好主意。但我会说尽可能少地投入以鸟瞰您的程序是如何工作的。

因此,我认为您在实现主要功能时最大的担忧应该是可读性。

于 2008-12-08T02:40:47.867 回答