У моей компании есть библиотека интеграций с общим «фронтом». Один из наших продуктов - это простой веб-заказ, и с нашей интеграционной библиотекой мы можем добавлять встречи в несколько внешних систем - от Microsoft Exchange и Google Calendar до регистров регистрации в системах EMR. В этой библиотеке имеется 28 интеграций.Структура библиотеки интеграции
Это упрощенный пример того, как обрабатываются некоторые запросы времени для интеграции в SystemA и SystemB.
Параметры GetTimes
фактически связаны в GetTimesParameters
объекте, но представлены здесь в виде отдельных входных параметров.
Чтобы использовать библиотеку интеграции мы имеем простой фабричный метод, возвращающий ImplementationBase
объекта и библиотеку расширения для преобразования объекта ImplementationBase в различные интерфейсы:
// Create ImplementationBase object
var implementation = ImplementationFactory.Create(ImplementationEnum.SystemA);
// Set implementation connection data
implementation.SetConnection("...");
// Get an ITime object
var timeImplementation = implementation.AsTime();
// Get the times from today and two days forward
var times = timeImplementation.GetTimes(DateTime.Today, DateTime.Today.AddDays(2));
Метод расширение AsTime()
бросает определенное исключение, если интерфейс не реализуется реализацией.
Это работает достаточно хорошо, но его немного сложно поддерживать.
Простая проверка - это одно. В вызове GetTimes
мы проверяем, есть ли from
DateTime до to
DateTime - это сделано всеми реализациями GetTime
.
Другая проблема заключается в том, как обрабатываются не используемые методы. Методы GetTimes
и GetTimeTypes
почти всегда используются вместе. Но в одной интеграции нет типов времени. Метод GetTimeTypes()
выбрасывает ImplementationMethodNotSupportedException()
, а параметр timeTypeId
в GetTimes
игнорируется.
Я уверен, что есть и другие проблемы, но эти два приходят на ум только сейчас, и проблема проверки вызывает наибольшие головные боли.
Я хочу новый слой поверх этого. Там, где может быть разрешена общая проверка, и, возможно, где приложение может переопределить поведение - например, обработать ImplementationMethodNotSupportedException
в примере GetTimeTypes
как возвращающий пустой список типов времени.
Но я не уверен, как это сделать. Любые предложения по улучшению нашего подхода или полного ремоделирования были бы замечательными!
Мы не хотим, чтобы классы параметров имели конструкторы, но мы могли бы добавить к нему метод Validate и вызвать этот метод в каждой реализации. –
Почему бы и нет? Конструкторы существуют по какой-то причине. Так как .NET допускает синтаксис инициализации, все больше программистов забывают о конструкторах. И эти классы содержат конструктор, а именно, что вы не заставляете его работать на вас. Если вы добавите метод Validate, вы все равно должны будете его вызвать в любом из 28 классов реализации - DRY. –
Вы правы, и я это рассмотрю. –