新创建的类是否应该“开始”?施工期间本身?

发布于 2024-11-18 08:43:27 字数 726 浏览 5 评论 0原文

上下文:.NET、C#,但问题总体上是关于 OOP 的。

当我编写一个应该充当“服务”的类(例如套接字侦听器或计时器)时,我在编码时看到两种方法:

  1. 创建一个构造函数,并在构造函数内立即启动后台任务。例如:

    公共类MyTimer
    {
        私有只读 TimeSpan 间隔;
    
        公共MyTimer(时间跨度间隔)
        {
            this.interval = 间隔;
            开始计时();
        }
    
        私有无效 StartTicking()
        {
            // 执行滴答逻辑
        }
    }
    
  2. 创建一个接受类设置的构造函数,并添加一个显式的启动方法:

    公共类MyTimer
    {
        私有只读 TimeSpan 间隔;
    
        公共MyTimer(时间跨度间隔)
        {
            this.interval = 间隔;
        }
    
        公共无效开始计时()
        {
            // 执行滴答逻辑
        }
    }
    

我倾向于认为第二种方法更好:

A. 构造函数仅用于创建有效实例,保持最小化和干净。

B. 实际使用我的类的开发人员并不那么惊讶。

C. 硬件资源没有被过度使用,因为“服务”类不会立即使用它们。

你怎么认为?这只是编码风格的问题,还是不止于此?

Context: .NET, C#, but the question is about OOP in general.

When I write a class that should act as a "service", like a socket listener, or a timer, I see two approaches when it comes to coding it:

  1. Create a constructor, and inside the constructor, immediately start the background task. For instance:

    public class MyTimer
    {
        private readonly TimeSpan interval;
    
        public MyTimer(TimeSpan interval)
        {
            this.interval = interval;
            StartTicking();
        }
    
        private void StartTicking()
        {
            // do the ticking logic
        }
    }
    
  2. Create a constructor that accepts the class' settings, and add an explicit method for starting up:

    public class MyTimer
    {
        private readonly TimeSpan interval;
    
        public MyTimer(TimeSpan interval)
        {
            this.interval = interval;
        }
    
        public void StartTicking()
        {
            // do the ticking logic
        }
    }
    

I tend to think that the second approach is better:

A. The constructor is used only for creating a valid instance, keeping it minimal and clean.

B. The developer who actually uses my class is less astonished.

C. The hardware resources are not overused, since the "service" class does not immediately use them.

What do you think? Is it only a matter of coding style, or is it more than that?

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

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

发布评论

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

评论(3

萌能量女王 2024-11-25 08:43:27

保持构造函数最小化,并要求调用代码调用特定的函数,以便执行除最简单的初始化之外的任何操作。这就是 .NET 中 Stopwatch 类的作用,例如。

除了避免调用构造函数的人感到意外之外,这还允许您更好地利用依赖注入(即将您的类注入到需要它的类的构造函数中,但不想以正确的方式使用它)。

我还发现,某些类型的错误在构造函数中发生时比在其他方法中发生时更难捕获。

Keep your constructor minimal, and require the calling code to call a specific function in order to do anything but the most simple initialization. This is what the Stopwatch class does in .NET, for instance.

Besides avoiding surprises for the person invoking the constructor, this also allows you to make better use of Dependency Injection (i.e. having your class injected into the constructor of a class that needs it, but which doesn't want to use it right way).

I've also found that certain types of bugs are more difficult to catch when they occur in constructors than when they are in some other method.

恬淡成诗 2024-11-25 08:43:27

不要在构造函数中开始运行。

  • API 的用户不会想到这一点,这会使您的类更难使用。
  • 从异常处理的角度来看,您希望能够报告构造对象时发生的错误,与执行期间发生的错误分开。
  • 如果您想要执行静态工厂单例模式之类的操作,它会阻止共享对象的实例。
  • 我赞同 StriplingWarrior 的观点,即有很多很好的理由,例如依赖注入,需要首先创建对象,以便其他类可以稍后运行它。

Don't start running in your constructor.

  • Users of your API won't expect that, and it makes your class harder to use
  • From an exception handling standpoint, you want to be able to report an error that happens when constructing an object, separately from an error that happens during execution.
  • It prevents sharing instances of your object, if you ever wanted to do something like a static factory singleton pattern.
  • I would second StriplingWarrior's point that there are many good reasons, like dependency injection, where object creation needs to happen first so that some other class can run it later.
玉环 2024-11-25 08:43:27

我见过的几乎每个服务类型类都公开了启动和停止它的方法。如果它是自动启动的,通常是非常明确的(类名可能是 MyAutostartingTimer 或其他名称..)

Nearly every service-type class that I've seen exposes methods to start and stop it. If it is auto-starting, it is usually very explicitly so (the class name might be MyAutostartingTimer or something..)

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