开发者

Should a newly created class "start" itself during construction?

开发者 https://www.devze.com 2023-03-16 19:46 出处:网络
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

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 MyTime开发者_如何学Gor(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?


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.


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.


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..)

0

精彩评论

暂无评论...
验证码 换一张
取 消