Как принцип "открытый / закрытый" может помочь избежать повторного развертывания сборок?
Я недавно прочитал хорошую, простую для понимания статью оopen/closed principle
, И меня удивил следующий опыт:
В реальном сценарии, когда база кода в десять, сто или тысяча раз больше, и изменение класса означает повторное развертывание его сборки / пакета на пяти разных серверах, что может быть довольно большой проблемой. Да, и в реальном мире Олдфорд изменил бы требования еще пять раз, так как вы прочитали последнее предложение:-)
Как open/closed principle
может помочь избежать повторного развертывания сборок?
1 ответ
Как вы знаете, принцип открытия / закрытия может быть реализован различными способами в зависимости от сценария. Для сценария позднего связывания сборки принцип открытия / закрытия будет означать для меня программирование на основе интерфейсов для частей кода, где эти незначительные / существенные изменения могут произойти во времени.
Дополнительная информация о позднем связывании: https://en.wikipedia.org/wiki/Late_binding
Вскоре позднее связывание происходит в контексте, о котором я упоминаю, это возможность выбрать DLL для загрузки во время выполнения в нашей программе.
Я попытаюсь объяснить это на примере. Если у нас есть приложение, которое является огромным, и второстепенная часть функциональности, которая обеспечивает, делает некоторые вычисления (скажем, это добавляет числа)
ICalculator
{
int Add(int a, int b);
}
DLL, которая содержит интерфейс калькулятора, - Application.Calcualtion.dll и код, использующий ICalculator
Интерфейс в DLL может иметь некоторую функцию Boostrapp/Init, которая будет создавать конкретную реализацию калькулятора.
А вот и поздний переплет.
Вместо того, чтобы использовать что-то вроде Calculator = new ConcreteCalculator()
, вы можете загрузить DLL с реализацией интерфейса ICalculator из определенного места.
using Assemnly.LoadFile(path: "....")
тогда вы можете запросить сборку для интерфейса, используя что-то вроде этого
var calculatorType = assembly.ExportedTypes.OfType<ICalculator>().Single();
Обычно DLL может быть загружен из определенного места. Таким образом, когда реализация калькулятора должна быть изменена, обновление приложения может развернуть только новую DLL-библиотеку с реализацией ICalculator в определенном месте, куда вы добавляете библиотеку DLL.
Подход позднего связывания смотрел под другим углом только на принцип инверсии зависимостей, но также позволяет расширять / изменять поведение ваших функций вычисления без изменения исходного кода в приложении.
Надеюсь это поможет.