У нас есть зависимость от стороннего сервиса, который предоставляет гигантский интерфейс, который нам нужен только как 3 метода. Кроме того, интерфейс часто меняется ...
Я решил обернуть интерфейс в класс в нашем проекте и раскрыть только те методы, которые нам нужны.
Но я не уверен, как я должен обрабатывать возвращаемые значения ... Интерфейс возвращает объект типа Storage
. У нас внутри есть тип, StorageModel
который является нашим внутренним представлением Storage
.
Что бы вы вернули в картограф: Storage
или StorageModel
? У нас есть DataService, StorageService
который получает зависимость от вложенной оболочки.
В настоящее время я делаю это в основном так:
public class StorageService
{
private readonly IExternalStorageWrapper externalStorageWrapper;
public StorageService(IExternalStorageWrapper externalStorageWrapper)
{
this.externalStorageWrapper = externalStorageWrapper;
}
public StorageModel GetStorage(int storageId)
{
return this.externalStorageWrapper.GetStorage(storageId).ConvertToStorageModel();
}
}
public class ExternalStorageWrapper : IExternalStorageWrapper
{
public Storage GetStorage(int storageId)
{
using(var ext = new ExternalStorage())
{
return ext.GetStorage(storageId);
}
}
}
Что бы вы сказали:
- Это хорошо, как и выше, что оболочка возвращает внешний
Storage
объект, а внутреннийStorageService
возвращает внутреннийStorageModel
? - Или вы бы вернули
StorageModel
в обертке уже?
Ответы:
По моему мнению, оболочка должна иметь дело со всеми вещами, связанными с внешней библиотекой. Это означает, что открытый интерфейс Wrapper не должен называть какие-либо внешние типы.
Сопоставление внешних типов с соответствующими типами вашего приложения является частью обязанностей оболочки. Если это не тривиальная операция, вы можете использовать различные инструменты, доступные для декомпозиции проблемы, например внедрение объекта-переводчика. Однако переводчик все еще должен быть частью вашего модуля-оболочки, и никакая другая часть вашего приложения не может зависеть от него.
Таким образом, остальная часть вашего приложения будет полностью защищена не только от изменений в библиотеке, но и от замены библиотеки другой.
источник
Это нормально. Это также называется адаптером .
Вы выбираете шаблон адаптера , поэтому цель здесь - преобразовать один интерфейс (модель библиотеки) в другой (модель предметной области). Таким образом, если что-то из первого достигает доменной модели, адаптер не справляется со своей задачей .
Согласно предыдущим аргументам адаптер должен возвращать
StorageModel
.В конечном счете, ваш домен «говорит» язык конкретно, где
Storage
это незнакомец .Ключевым моментом здесь является знать, по какой причине вы упаковываете / адаптируете библиотеку .
Шаблоны Adapter, Decorator, Facade могут иметь сходство, но они довольно разные. Как и проблемы, которые они решают.
Тем не менее, вы также можете быть заинтересованы в:
Рисунок фасада (сложность укрытия)
Шаблон декоратора (улучшение интерфейса) . Когда его использовать
Различия между шаблоном адаптера и шаблоном прокси .
Что такое антикоррупционный слой и как он используется (скрывая некачественный и грязный код)
источник
Вы не можете эффективно обернуть библиотеку, дублируя ее.
То, что вам следует обернуть, - это использование библиотеки, а это означает, что она не раскрывает объекты, в данном случае Storage. Не пытайтесь их дублировать.
Используйте библиотеку, но храните ее. Так что в вашем случае, если вы используете StorageService для хранения вещей, вы должны обернуть его в репозитории
где MyPocoObject - полностью ваши данные и бизнес-логика. Не дублирование хранилища или DataReader или чего-либо
источник
Ответ в том, что это зависит от того, нужен ли вам доступ
Storage
напрямую из класса, который не нуженStorageModel
.Если вы собираетесь обернуть библиотеку, имеет смысл также обернуть возвращаемый ею объект, чтобы в будущем вы могли проверить изменения, внесенные библиотекой. Однако, если вам когда-либо понадобится использовать
Storage
напрямую, это может означать, что вам может понадобиться вернуться вStorage
зависимости от ситуации. Можно привести аргумент в пользу того, чтобыStorage
использование здесь было таким,StorageModel
каким вы, вероятно, хотите оставаться последовательным во всей вашей программе.Я настоятельно рекомендую вам обернуть интерфейс и возвращаемый объект, если вы этого еще не сделали, хотя, опять же, это имеет смысл, только если вы используете только
StorageModel
в своей программе, а неStorage
.источник