Як перетворити послугу, щоб вона була простішою


11

Ми маємо залежність від стороннього сервісу, який виявляє гігантський інтерфейс, нам потрібні лише три методи. Крім того, інтерфейс часто змінюється ...

Я вирішив зафіксувати інтерфейс у класі в нашому проекті і лише розкрити потрібні нам методи.

Але я не впевнений, як мені обробляти повернені значення ... Інтерфейс повертає об'єкт типу 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коробку в обгортці?

2
Чому ви називаєте це обгорткою? Краще шукайте фасадну, мостову та адаптерну схему. Як я розумію, обгортка надає всі методи стороннього обслуговування - але це не те, що ви хочете.
Тобіас Отто


@TobiasOtto для обгортки не потрібно викривати всю поведінку загорнутого об'єкта, див. Цю статтю в "Обмеженій обгортці".
guillaume31

Відповіді:


11

На мій погляд, обгортка повинна мати справу з усіма речами, що стосуються зовнішньої бібліотеки. Це означає, що публічний інтерфейс Wrapper не повинен називати жодних зовнішніх типів.

Зображення зовнішніх типів до відповідних типів вашої програми є частиною обов'язків обгортки. Якщо це не тривіальна операція, ви можете використовувати різні інструменти, доступні для розкладання проблеми, наприклад, введення об’єкта перекладача. Однак перекладач все ж повинен бути частиною вашого модуля обгортки, і жодна інша частина вашої програми не може залежати від нього.

Таким чином, решта вашої програми повністю захищена не лише від змін у бібліотеці, а й від заміни бібліотеки на іншу.


3

Я вирішив зафіксувати інтерфейс у класі в нашому проекті і лише розкрити потрібні нам методи.

Це добре. Це також відоме як адаптер .

Ви вибираєте шаблон адаптера , тому метою тут є перетворення одного інтерфейсу (бібліотечної моделі) в інший (модель домену). Отже, якщо щось із колишнього досягає доменної моделі, адаптер не відповідає своєму призначенню .

Відповідно до попередніх аргументів, адаптер повинен повернути StorageModel.

Зрештою, ваш домен "розмовляє" певною мовою, де чужаStorage людина .

Але я не впевнений, як мені обробляти повернені значення ...

Головне тут - знати, з якої причини ви перегортаєте / адаптуєте бібліотеку .

Моделі адаптерів, декораторів, фасадів можуть мати подібності, але вони досить різні. Настільки ж різні, як проблеми, які вони вирішують.

Однак це може вам зацікавити:


1

Ви не можете ефективно обернути бібліотеку, копіюючи її.

Те, що вам слід перетворити, - це використання бібліотеки, а це означає, що не виставляти на неї об’єкти, в даному випадку - Storage. Не намагайтеся копіювати їх також.

Використовуйте бібліотеку, але зберігайте її. Тож у вашому випадку, якщо припустити, що ви використовуєте StorageService для зберігання речей, вам слід обернути їх у сховищах

MyPocoObjectRepo
    MyPocoObject GetObject(string id);

де MyPocoObject повністю ваші дані та бізнес-логіка. Не дублювання Storage або DataReader чи будь-чого іншого


0

Відповідь полягає в тому, що це залежить від того, чи потрібно вам коли-небудь звертатися Storageбезпосередньо з класу, який не є StorageModel.

Якщо ви збираєтеся обгортати бібліотеку, має сенс також обернути повернений нею об’єкт, щоб у майбутньому ви могли підтвердити зміни, внесені бібліотекою. Однак якщо вам коли-небудь потрібно буде користуватися Storageбезпосередньо, це означає, що може виникнути потреба повернутися Storageвідповідно до ситуації. Можна аргументувати те, що зобов’язання Storageвикористання тут є StorageModelтаким, яким ви, ймовірно, хочете залишатися послідовними протягом усієї програми.

Я б настійно рекомендував вам обернути як інтерфейс, так і повернутий об'єкт, якщо ви цього ще не робите, хоча це ще раз, це має сенс лише в тому випадку, якщо ви використовуєте лише StorageModelвсю програму, а ні Storage.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.