Зависимости порядка конструктора / деструктора между элементами данных

Я создаю класс C ++ для выполнения команд SSH, используя libssh2.

Жизненный цикл SSH-сессии libssh2 проходит следующие этапы:

  1. Инициализация (приобретает местные ресурсы)
  2. Рукопожатие / Аутентификация (устанавливает сеанс SSH на удаленном
    хостов)
  3. Отключиться (завершает сеанс SSH на удаленном хосте)
  4. Бесплатно (освобождает локальные ресурсы; при необходимости также выполняет шаг 3).

Перед шагом 1 мы должны открыть сокет, который мы передаем libssh2 на шаге 2. С этого момента нам больше не нужно передавать сокет, так как libssh2 будет хранить ссылку на него. После шага 4 мы можем закрыть сокет.

Я разоблачаю это через класс (SSHSession) и я бы хотел настроить (шаги 1 и 2) произойти на ctor и срывать (шаги 3 и 4), которые должны выполняться в dtor (поскольку шаг 2 занимает много времени, это позволит мне сохранить пул сессий открытым и использовать его для выполнения команд).

Моя первая попытка сосредоточить весь код на SSHSessionи его ctor быстро превратился в беспорядок, с рутиной «если этот шаг не пройден, тогда мы должны увидеть, что уже сделано и отменить это»; Дтор был не так сложен, но я все же нашел его слишком «занятым».

Затем я разделил работу между несколькими классами, реализуя RAII для каждого шага получения / выпуска, а именно:

  • Шаги 1 и 4.
  • Шаги 2 и 3.

Я создал класс SessionConnection который реализовал шаги 2 и 3, и имел член типа SessionHandle которые реализовали шаги 1 и 4; он также имел сокет в качестве члена данных, создавая зависимость первого порядка от ctor / dtor — сокет не мог быть уничтожен до SessionHandle член.

Рассматривая свой дизайн, я решил, что могу организовать шаги 2 и 3 следующим образом:

2.1. Handshake (устанавливает сеанс SSH на удаленном хосте)

2.2. Аутентификация

3. Отключение (завершает сеанс SSH на удаленном хосте)

Что означает, что я мог бы еще больше упростить мой SessionConnection class, реализуя другой класс для выполнения RAII на шагах 2.1 и 3, и заканчивая чем-то вроде этого:

  • Учебный класс SSHSession имеет SessionConnection элемент данных.
  • Учебный класс SessionConnection реализует шаг 2.2.
  • SessionConnection имеет элемент данных сокета.
  • SessionConnection имеет SessionHandle элемент данных, который реализует шаги 1 и 4. Это должно быть уничтожено перед сокетом.
  • SessionConnection имеет RemoteSessionHandle элемент данных, который реализует шаги 2.1 и 3. Он должен быть создан после и уничтожен до SessionHandle элемент данных.

Это значительно упрощает мои ctors / dtors, любезно предоставленные RAII. И я нахожу концептуально звук; если, с одной стороны, мы можем рассматривать их как состояния, через которые проходит сеанс SSH, с другой стороны, мы также можем видеть их как ресурсы (локальные, удаленные), которыми мы управляем.

Однако теперь у меня строгий порядок строительства / уничтожения в SessionConnectionи хотя я считаю, что это улучшение (и я не нашел ничего в своем исследовании, в котором говорилось, что «это зло», только «это должно быть четко задокументировано»), мне интересны другие мнения, и я с радостью приму информацию / указатели о возможных альтернативах этой конструкции.

На что я смотрел, пока:

  • ScopeGuard, ScopeExit. Это похожий механизм, я не нашел
    все, что я мог бы использовать в качестве улучшения моего дизайна.
  • Государственный аппарат. Я не мог найти способ упростить дизайн с ним,
    и это не решило одну проблему, которую делает RAII, а именно, очистку, если что-то не получается.

Спасибо за ваше время.

1

Решение

Кажется, в этом дизайне нет ничего принципиально неправильного.

Если вы хотите снять ограничение на порядок строительства / уничтожения членов SessionConnectionВы могли бы сделать следующее:

  • Учебный класс SSHSession
    • реализует шаг 2.2
    • имеет SSHConnection член
  • Учебный класс SSHConnection
    • реализует шаги 2.1 и 3
    • имеет LocalSessionHandle член
  • Учебный класс LocalSessionHandle
    • реализует шаги 1 и 4
    • имеет Socket член

Определенный порядок построения / уничтожения элементов и их содержащих классов обеспечивает выполнение шагов в правильном порядке.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]