28

我正在开发一个相当大的应用程序和我的技术主管,但我在某些事情上并没有意见一致。

其中之一是关于控制台应用程序。这些应用程序正在从 shell 脚本移植到 C#。其中一些脚本相当大(转换后的代码为 300-400 行),并执行 I/O、电子邮件和数据库访问等操作。

对于这些脚本中的每一个,我都创建了一个类。每个类都有一个 Run 方法,该方法调用其中的任何方法/操作。在 Program.cs/main 中,我创建了一个该类的对象并调用 Run。Program.cs 包含 4-5 行代码。干净简单。

我的技术主管想要摆脱脚本类,只将所有内容都放在 program.cs 的主要方法中。他的理由是它的方式太令人困惑了。

这样做感觉很尴尬,因为类不再可重用/可打包到类库中,而不必摆弄 main 方法。

单元测试似乎不受影响,因为您可以实例化 Program.cs 本身,但同样......这感觉很笨拙。以我没有看到的方式这样做有什么好处吗?我的方式有什么好处吗?在您的 main 方法中处理大型应用程序和内容时,是否有一般做法?

感谢您的时间。

4

8 回答 8

35

It feels awkward having to do it this way as the class no longer becomes reusable/package-able into a class library without having to fiddle with the main method.

It doesn't have to be that way.

For example, each of your scripts could still have the same structure it does, but also have a private static void Main(string[] args) method. (It could be non-private if you want - it all depends on your needs.)

That way it's standalone (can be compiled as a single input to a single output then run) which can occasionally be handy, but could also be used as part of a class library. The presence of a Main method in no way prevents the class being used from other classes, after all.

It's not clear whether you've got one Program.cs file or one per script. If you've got one per script, each of which is just 4-5 lines, that does seem somewhat pointless.

Now this certainly wouldn't be how I'd normally structure a large application - but if the point is to have several "scripts" each of which can be run standalone, then giving each class a Main method doesn't seem too bad.

In fact, what I often do for demo purposes is have several classes with Main methods in a single project, then have a separate entry point (which is in Program.cs) which uses reflection to find all the others and then allows the user/presenter to choose which one to run.

If all your code makes sense to have in a single class, then having a tiny extra entry method doesn't seem such a problem. If it's actually a case of too much code for a single class regardless of where the entry point is, that's a different matter. (So if you stuck to having a single ScriptClass when actually you should give different tasks to different classes, that would be bad too.) Likewise if he really is insisting on all the code being in a single method, that's definitely a problem for testing and maintainability.

I suggest you set the entry point disagreement aside for the moment: work out the cleanest way to structure everything else about the code, and then it really doesn't matter whether the Main method goes in Program.cs or within another class.

于 2012-10-15T22:09:08.163 回答
4

老实说,我认为您正在为自己创造工作。我无法从您描述中的细节中看出 - 但如果 shell 脚本一直在工作,为什么要在显然不需要结构的地方构建它?

你说模块化和重新打包到外部库是你需要做的事情——我会反驳“为什么?” (这就是我所说的额外工作)。

如果您在单个文件中创建一组简单的方法 - 那就是一个文件!根据定义,它会更容易处理多个项目等。

也就是说——除非有更多细节,否则很难知道我们在说什么。如果它是“发送夜间报告并向这些人发送电子邮件” - 是的,这不需要类库和大量模块化。运行一个方法,你就完成了。

于 2012-10-15T22:23:44.037 回答
4

您确实知道控制台应用程序的入口点是可配置的,对吧?

我的首选方法是:

class MeaningfullyNamedProgram { 
    public static void Main(string[] args) {
        var program = new MeaningfullyNamedProgram(args);
        program.Run();
    }

    public MeaningfullyNamedProgram(string[] args) { 
    }

    public Run() {
        // well structured, broken-out code follows 
    }
}

将项目的入口点指向 MeaningfullyNamedProgram.Main

注意:我将把它作为练习留给读者,但您可以使用泛型为此创建一个基类,并为自己节省一些输入。

于 2012-10-15T22:48:46.610 回答
3

Your tech lead needs a good talking to! Putting everything into the Program.cs is not the way forward.

于 2012-10-15T22:08:37.220 回答
3

Well, his way is conceptually simpler, in that it's how programs were written before the subroutine was invented ....

Your way is better: it supports reusability and would be easier to modify and to debug.

The only other justification I can think of for his way was that if it was taking significantly longer for you to do it your way than it would be to do it his way. But that's a case of short-term thinking on his part. Your way will stand the test of time better.

于 2012-10-15T22:10:41.937 回答
2

Your tech lead is wrong. The method you propose is a lot more reasonable -- it allows for the consolidation of different scripts easily. Each script having its own Main method can get clunky, especially if you are planning on having an application that can run several of these at a time.

于 2012-10-15T22:11:11.070 回答
1

Splitting the logic out into a separate class (or classes) is the way to go. Putting it all into one spot violates the principles of SOLID and DRY design. You're definitely on the right track with your approach.

The more you keep your classes focused on single roles the easier your life will be for maintenance and testing.

于 2012-10-15T22:10:39.693 回答
1

如果该功能可以通过控制台程序以外的其他方式使用,那么您当然应该将它们保存在一个模型良好的类库中。考虑到关注点最初是分开的,通过使用封装的功能来处理命令行参数来节省几行代码是没有意义的。恕我直言,也许您的技术主管应该为您找到更有成效的任务。

于 2012-10-15T22:13:33.143 回答