Использование класса Builder для воссоздания набора дочерних объектов с использованием DI?

#c# #oop #dependency-injection #builder

#c# #ооп #внедрение зависимостей #Конструктор

Вопрос:

У меня есть класс запроса, который используется для извлечения файлового ресурса из внешнего процесса с помощью метода RetrieveResource() . Выполнение этого метода занимает примерно 10-15 секунд. Кроме того, Request класс содержит четыре дочерних объекта, которые создаются с помощью внедрения зависимостей во время построения класса для доступа к содержимому запрошенного файла.

Экземпляр Request класса создается из основного класса проекта. Основной класс вызывается RetrieveResource() примерно каждые 30 секунд. После каждого вызова может потребоваться настроить конкретное свойство, например, свойство A, одного или нескольких дочерних объектов Request класса.

Мне было бы интересно услышать мнения о наилучшем способе достижения этой цели. В следующем списке описаны три подхода, которые можно использовать для изменения значения свойства A:

  1. Основной класс явно устанавливает значение свойства A для каждого дочернего объекта объекта запроса путем прямого вызова свойства. Например, Request.Object1.PropertyA = newValue;

  2. Создайте метод в классе Request для обновления значения свойства A для каждого дочернего объекта, например, UpdatePropertyA()

  3. При создании экземпляра Request класса передайте класс builder, который отвечает за создание нового Request экземпляра, включая создание каждого из четырех объектов с использованием DI. Класс builder содержит свойство, например, свойство A, которое затем используется для установки значения свойства имени для каждого дочернего объекта класса запроса.

Благодарен за то, что услышал мысли. Спасибо.

Ответ №1:

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

Лично я бы предложил слегка измененный третий подход, потому что он переносит всю логику обновления на объект builder, что является хорошим и гибким решением. Я бы сказал, что у этого объекта должен быть, скажем BuildUp(Request instance) , метод, и внутри этого метода должно происходить все обновление. Способ, которым вы реализуете фактическое обновление, здесь не имеет значения — все это будет оставлено в стороне в специальном классе, и в случае каких-либо изменений его можно будет изменить в мгновение ока, без изменения основной логики классов приложения.

Кроме того, вы можете захотеть создать интерфейс для этого builder и работать с интерфейсом только в коде Resource класса. Это будет основной класс, который будет знать о фактической реализации используемого builder . Таким образом, замена реализации builder в случае каких-либо изменений была бы делом одной строки.

Комментарии:

1. Спасибо за ваш комментарий. Я разработал класс builder для облегчения создания новых экземпляров объекта запроса, используя заданное значение для свойства A. Этот подход хорошо работает и представляет собой согласованный и слабо связанный дизайн. Я решил не реализовывать первые два подхода по тем же причинам, которые вы упомянули. Целью этого вопроса было определить и обсудить причины, по которым следует избегать второго и третьего подходов. Ваш ответ поднимает ряд хороших моментов. Спасибо!