Должен ли недавно созданный класс «начинать» себя во время строительства? - PullRequest
0 голосов
/ 01 июля 2011

Контекст: .NET, C #, но вопрос о ООП в целом.

Когда я пишу класс, который должен действовать как «служба», например, слушатель сокета или таймер, я вижу два подхода к его кодированию:

  1. Создайте конструктор, и внутри конструктора немедленно запустите фоновую задачу. Например:

    public class MyTimer
    {
        private readonly TimeSpan interval;
    
        public MyTimer(TimeSpan interval)
        {
            this.interval = interval;
            StartTicking();
        }
    
        private void StartTicking()
        {
            // do the ticking logic
        }
    }
    
  2. Создайте конструктор, который принимает настройки класса, и добавьте явный метод для запуска:

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

Я склонен думать, что второй подход лучше:

A. Конструктор используется только для создания действительного экземпляра, сохраняя его минимальным и чистым.

B. Разработчик, который фактически использует мой класс, менее удивлен.

C. Аппаратные ресурсы не используются чрезмерно, поскольку класс «service» не использует их сразу.

Что ты думаешь? Это только вопрос стиля кодирования или больше?

Ответы [ 3 ]

1 голос
/ 01 июля 2011

Держите ваш конструктор минимальным и требуйте, чтобы вызывающий код вызывал определенную функцию, чтобы сделать что-нибудь кроме самой простой инициализации. Это то, что класс Секундомер делает, например, в .NET.

Помимо избежания неожиданностей для человека, вызывающего конструктор, это также позволяет вам лучше использовать Dependency Injection (т.е. внедрить ваш класс в конструктор класса, который нуждается в нем, но который не хочет использовать его правильно путь).

Я также обнаружил, что некоторые типы ошибок труднее выявлять, когда они встречаются в конструкторах, чем в каком-либо другом методе.

0 голосов
/ 01 июля 2011

Не запускайте в своем конструкторе.

  • Пользователи вашего API этого не ожидают, и это затрудняет использование вашего класса
  • С точки зрения обработки исключений вы хотите иметь возможность сообщать об ошибке, возникающей при построении объекта, отдельно от ошибки, возникающей во время выполнения.
  • Это предотвращает совместное использование экземпляров вашего объекта, если вы когда-либо хотели сделать что-то вроде статического фабричного одноэлементного шаблона.
  • Я бы поддержал замечание StriplingWarrior о том, что есть много веских причин, таких как внедрение зависимостей, когда создание объекта должно произойти в первую очередь, чтобы какой-то другой класс мог запустить его позже.
0 голосов
/ 01 июля 2011

Почти каждый класс типа обслуживания, который я видел, предоставляет методы для его запуска и остановки. Если это автозапуск, это обычно очень явно (имя класса может быть MyAutostartingTimer или что-то в этом роде).

...