Використання сторонніх бібліотек - завжди використовувати обгортку?


78

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

Наприклад, більшість наших PHP-проектів безпосередньо використовують log4php як систему реєстрації, тобто вони створюють екземпляр через \ Logger :: getLogger (), вони використовують -> info () або -> warn () методи тощо. Надалі, однак може з’явитися гіпотетична рамка ведення журналу, яка в чомусь краща. На сьогоднішній день усі проекти, які тісно поєднуються з підписами методу log4php, повинні були б змінитися в десятках місць, щоб відповідати новим підписам. Це, очевидно, мало б великий вплив на кодову базу, і будь-які зміни є потенційною проблемою.

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

Маючи на увазі, що з іншими бібліотеками є більш складні приклади, я переробляю техніку чи це в більшості випадків мудрий запобіжний захід?

EDIT: Більше міркувань - використання подвійних ін'єкцій залежностей і тестування практично вимагає, щоб ми все-таки абстрагували більшість API ("Я хочу перевірити, чи виконується код і оновить його стан, але не писати коментарі до журналу / отримати доступ до реальної бази даних"). Це не рішення?


3
log4XYZ - така сильна торгова марка. Його API зміниться не раніше, ніж з'явиться API для пов'язаного списку. Обидва - це давно вирішена проблема.
робота

1
Точний дублікат цього питання ТА
Michael Borgwardt

1
Якщо ви просто використовуєте його внутрішньо, то чи загортаєте ви, чи ні, це лише компроміс між відомою роботою зараз та можливою роботою пізніше. Виклик суду. Але, здається, щось інше з респондентів знехтувало говорити, чи це залежність від API чи залежність від реалізації . Іншими словами, ви витікаєте з класів цього третьої сторони API через свій власний загальнодоступний API та наражаєте його на користувачів? У цьому випадку перейти до іншої бібліотеки - це вже не проста справа важкої роботи, проблема полягає в тому, що зараз неможливо без порушення власного API. Це дуже погано!
Ілля Василенко

1
Для подальшого ознайомлення: Цей шаблон називається луковою архітектурою, де зовнішня інфраструктура (ви називаєте її зовнішньою lib) прихована за інтерфейсом
k3b

Відповіді:


42

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

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


Хороші моменти, але нас вчать, що тісно пов'язаний код - це погано, з багатьох зрозумілих причин (складніше перевірити, складніше рефактору тощо). Альтернативним формулюванням питання є "якщо зв'язок поганий, чому в порядку з'єднання з API?".
lotoffreetime

7
@lotsoffreetime Ви не можете уникнути певного з'єднання з API. Тому краще приєднатися до власного API. Таким чином, ви можете змінити бібліотеку і взагалі не потрібно змінювати API, наданий обгорткою.
Джордж Маріан

@ george-marian Якщо я не можу уникнути використання заданого API, я, безумовно, можу мінімізувати точки дотику. Питання полягає в тому, чи варто мені намагатися це робити весь час чи це перестарання?
lotoffreetime

2
@lotsoffreetime На це складне питання відповісти. Я розширив свою відповідь з цією метою. (В основному, це дуже багато ifs.)
Джордж Маріан

2
@lotsoffreetime: якщо у вас багато вільного часу, ви можете робити будь-яке. Але я б рекомендував не писати обгортку API, за винятком цієї умови: 1) оригінальний API дуже низького рівня, тому ви пишете API більш високого рівня, щоб відповідати конкретному проекту, або 2) у вас є план у найближчим часом для переключення бібліотек, ви використовуєте поточну бібліотеку лише як сходинку під час пошуку кращої.
Лі Лі Раян

28

Не знаючи, які нові чудові функції матиме цей передбачуваний вдосконалений лісоруб, як би ви написали обгортку? Найбільш логічним вибором є наявність у вашої обгортки екземпляра якогось класу реєстратора та використання методів, таких як ->info()або ->warn(). Іншими словами, по суті ідентичний вашому теперішньому API.

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

По-іншому, обгортки дійсно мають сенс лише тоді, коли ви вже знаєте всі API, які вам потрібні. Хорошими прикладами є те, якщо вашій програмі в даний час потрібно підтримувати безліч різних драйверів баз даних, операційних систем або версій PHP.


"... обгортки дійсно мають сенс лише тоді, коли ви вже знаєте всі API, які вам потрібно завершити." Це було б правдою, якби я відповідав API в обгортці; можливо, мені слід використовувати термін "капсулювання" сильніше, ніж обгортку. Я б абстрагував ці виклики API, щоб "якось записати цей текст", а не "виклик foo :: log () з цим параметром".
lotoffreetime

"Не знаючи, які нові чудові функції матиме цей передбачуваний вдосконалений реєстратор, як би ви написали обгортку?" @ kevin-cline нижче згадує майбутнього реєстратора з кращою продуктивністю, а не новою функцією. У цьому випадку немає нового API для завершення, просто інший заводський метод.
lotoffreetime

27

Обгортаючи сторонні бібліотеки, ви додаєте додатковий шар абстракції поверх неї. У цього є кілька переваг:

  • Ваша кодова база стає гнучкішою до змін

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

  • Ви можете визначити API обгортки незалежно від API бібліотеки

    Різні бібліотеки можуть мати дуже різні API, і в той же час жодна з них не може бути саме тим, що вам потрібно. Що робити, якщо для кожної бібліотеки потрібен маркер, який потрібно передавати разом із кожним викликом? Ви можете передати маркер у вашому додатку, де вам потрібно використовувати бібліотеку, або зберегти його десь центральніше, але в будь-якому випадку маркер вам потрібен. Ваш клас обгортки знову робить це все простим - адже ви можете просто тримати маркер всередині свого класу обгортки, ніколи не піддаючи його жодному компоненту всередині вашого додатка і повністю абстрагуючи необхідність у ньому. Величезна перевага, якщо ви коли-небудь використовували бібліотеку, яка не підкреслює хороший дизайн API.

  • Тестування одиниць простіше

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

  • Ви створюєте нещільно пов'язану систему

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


Практичний приклад

Давайте будемо чесними. Люди можуть годинами сперечатися про переваги та недоліки чогось подібного - саме тому я набагато просто показую вам приклад.

Скажімо, у вас є якась програма для Android, і вам потрібно завантажити зображення. Існує купа бібліотек, які роблять завантаження та кешування зображень вітерцем, наприклад, Пікассо або Універсальний завантажувач зображень .

Тепер ми можемо визначити інтерфейс, який ми будемо використовувати, щоб обернути будь-яку бібліотеку, в якій ми знаходимося:

public interface ImageService {
    Bitmap load(String url);
}

Це інтерфейс, який ми зараз можемо використовувати у всьому додатку, коли нам потрібно завантажити зображення. Ми можемо створити реалізацію цього інтерфейсу і використовувати ін'єкцію залежності, щоб ввести примірник цієї реалізації скрізь, де ми використовуємо ImageService.

Скажімо, ми спочатку вирішили використовувати Пікассо. Тепер ми можемо написати реалізацію, для ImageServiceякої використовується Picasso внутрішньо:

public class PicassoImageService implements ImageService {

    private final Context mContext;

    public PicassoImageService(Context context) {
        mContext = context;
    }

    @Override
    public Bitmap load(String url) {
        return Picasso.with(mContext).load(url).get();
    }
}

Досить прямо, якщо ви запитаєте мене. Обертання навколо бібліотек не повинно бути складним, щоб бути корисним. Інтерфейс та реалізація мають менше 25 комбінованих рядків коду, тому створити це ледь не було, але ми вже щось отримуємо, роблячи це. Бачите Contextполе в реалізації? Ваша обрана система введення залежностей вже піклується про введення цієї залежності до того, як ми коли-небудь використовуватимемо нашу ImageService, ваш додаток тепер не повинен дбати про те, як завантажуються зображення та які б залежності не мали бібліотеки. Все, що бачить ваша програма, - це ImageServiceі коли йому потрібне зображення, з яким він дзвонить load()за допомогою URL-адреси - простий та простий.

Однак реальна користь приходить, коли ми починаємо щось змінювати. Уявіть, нам зараз потрібно замінити Picasso на Universal Image Loader, оскільки Picasso не підтримує якусь функцію, яка нам зараз потрібна. Чи нам тепер доводиться прочісувати нашу кодову базу і нудно замінювати всі дзвінки до Picasso, а потім вирішувати десятки помилок компіляції, оскільки ми забули кілька викликів Picasso? Ні. Все, що нам потрібно зробити, це створити нову реалізацію ImageServiceта сказати нашій системі введення залежності, щоб використовувати цю реалізацію відтепер:

public class UniversalImageLoaderImageService implements ImageService {

    private final ImageLoader mImageLoader;

    public UniversalImageLoaderImageService(Context context) {

        DisplayImageOptions defaultOptions = new DisplayImageOptions.Builder()
                .cacheInMemory(true)
                .cacheOnDisk(true)
                .build();

        ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(context)
                .defaultDisplayImageOptions(defaultOptions)
                .build();

        mImageLoader = ImageLoader.getInstance();
        mImageLoader.init(config);
    }

    @Override
    public Bitmap load(String url) {
        return mImageLoader.loadImageSync(url);
    }
}

Як бачите, реалізація може бути дуже різною, але це не має значення. Нам не довелося змінювати жодного рядка коду ніде в нашому додатку. Ми використовуємо зовсім іншу бібліотеку, яка може мати зовсім інші функції або може використовуватися зовсім по-іншому, але наша програма просто не хвилює. Так само, як і раніше, наша інша програма просто бачить ImageServiceінтерфейс зі своїм load()методом, проте цей спосіб реалізований вже не має значення.

Принаймні для мене це все вже звучить досить приємно, але зачекайте! Є ще більше. Уявіть, що ви пишете одиничні тести для класу, над яким ви працюєте, і цей клас використовує ImageService. Звичайно, ви не можете дозволити вашим тестовим підключенням здійснювати мережеві дзвінки на якийсь ресурс, розташований на якомусь іншому сервері, але оскільки ви зараз використовуєте, ImageServiceви можете легко дозволити load()повернути статику, Bitmapвикористану для тестів одиниці, застосувавши насмішку ImageService:

public class MockImageService implements ImageService {

    private final Bitmap mMockBitmap;

    public MockImageService(Bitmap mockBitmap) {
        mMockBitmap = mockBitmap;
    }

    @Override
    public Bitmap load(String url) {
        return mMockBitmap;
    }
}

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


1
Це також стосується і нестабільного API. Наш код не змінюється в 1000 місцях лише тому, що основна бібліотека змінилася. Дуже приємна відповідь.
RubberDuck

Дуже лаконічна і чітка відповідь. Я роблю передню роботу в Інтернеті. Сума змін у цьому ландшафті божевільна. Те, що люди "думають", що їх не буде, не означає, що змін не буде. Я бачив згадки про ЯГНІ. Я хотів би додати нову абревіатуру, YDKYAGNI, ви не знаєте, що вам це знадобиться. Особливо з веб-реалізаціями. Як правило, я завжди обшиваю бібліотеки, які розкривають лише невеликий API (наприклад, select2). Більші бібліотеки впливають на вашу архітектуру, і їх обертання означає, що ви очікуєте зміни вашої архітектури, але це менше шансів.
Byebye

Ваша відповідь була дуже корисною, а представлення концепції на прикладі зробило концепцію ще більш зрозумілою.
Аніл Горті

24

Я думаю, що завершення роботи сторонніх бібліотек сьогодні, якщо завтра станеться щось краще, є дуже марним порушенням YAGNI. Якщо ви неодноразово телефонуєте стороннім кодом у спосіб, властивий вашій програмі, ви (повинні) переробляти ці виклики в клас обгортання, щоб виключити повторення. Інакше ви повністю використовуєте API бібліотеки, і будь-яка обгортка виглядатиме так само, як і сама бібліотека.

Тепер припустимо, що нова бібліотека з’являється з найкращою продуктивністю або будь-яким іншим. У першому випадку ви просто перезаписуєте обгортку для нового API. Нема проблем.

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


4
Я не думаю, що YAGNI обов'язково застосовується в цій ситуації. Справа не в створенні функціональних можливостей, якщо вам це знадобиться в майбутньому. Йдеться про створення гнучкості в архітектурі. Якщо ця гнучкість непотрібна, тоді так, застосовується YAGNI. Однак це визначення, як правило, буде здійснено десь у майбутньому, коли внесення змін, ймовірно, буде болючим.
Джордж Маріан

7
@George Marian: проблема - це 95% часу, вам ніколи не знадобиться гнучкість для зміни. Якщо вам потрібно перейти до майбутньої нової бібліотеки, яка має найкращі показники, тоді це буде досить тривіально для пошуку / заміни дзвінків або написання обгортки, коли вам це потрібно. З іншого боку, якщо ваша нова бібліотека має різні функції, обгортка тепер стає перешкодою, оскільки тепер у вас є дві проблеми: перенесення старого коду для використання нових функцій та підтримка обгортки.
Лі Лі Райан

3
@lotsoffreetime: Мета "гарного дизайну" - мінімізувати загальну вартість програми протягом її життя. Додавання шарів непрямості для уявних майбутніх змін - це дуже дороге страхування. Я ніколи не бачив, щоб хтось розумів економію від такого підходу. Це просто створює тривіальну роботу для програмістів, час яких набагато краще витратити на потреби клієнта. Більшість часу, якщо ви пишете код, не характерний для вашого замовника, ви витрачаєте час і гроші.
кевін клайн

1
@George: якщо ці зміни болючі, я думаю, що це запах процесу. У Java я створив би нові класи з тими ж іменами, що і старі класи, але в іншому пакеті змінив би всі входження старого імені пакета та повторно повторив автоматизовані тести.
кевін клайн

1
@kevin Це більше роботи і, таким чином, несе більше ризику, ніж просто оновлення обгортки та проведення тестів.
Джордж Маріан

9

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

Чи варто цього докласти зусиль - це інша історія. Ця дискусія, ймовірно, триватиме ще довго.

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

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


У випадку тестування одиниць, коли можливість ввести макет API служить мінімізації тестуваного блоку, "зміна потенціалу" не є фактором. Сказавши це, це все ще моя улюблена відповідь, оскільки вона найближча до того, як я думаю. Що сказав би дядько Боб? :)
lotoffreetime

Крім того, для невеликих проектів (відсутність команди, базових специфікацій тощо) є свої правила, за якими ви можете порушити належну практику, як-от ця, і певною мірою піти з нею. Але це вже інше питання ...
lotoffreetime

1

Окрім того, що вже сказав @Oded , я просто хотів би додати цю відповідь із особливою метою ведення журналу.


У мене завжди є інтерфейс для ведення журналів, але мені ніколи ще не доводилося замінювати log4fooрамки.

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

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


Я не сподіваюсь змінити log4foo, але він широко відомий і слугує прикладом. Цікаво також, наскільки дві відповіді поки доповнюють один одного - "не завжди обертай"; "обгортати про всяк випадок".
багаторазовий час

@Falcon: ти все обертаєш? ORM, інтерфейс журналу, основні класи мови? Зрештою, ніколи не можна сказати, коли може знадобитися кращий HashMap.
кевін клайн

1

Я маю справу з цим точним питанням над проектом, над яким зараз працюю. Але в моєму випадку бібліотека призначена для графіки, і тому я можу обмежити її використання невеликою кількістю класів, які займаються графікою, а не розповсюдженням її протягом усього проекту. Таким чином, досить легко перемикати API пізніше, якщо мені потрібно; у випадку з лісорубом справа стає набагато складнішою.

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


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

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


1

Я сильно перебуваю в обгортковому таборі і не маю можливості замінити бібліотеку третьої сторони найбільшою пріоритетністю (хоча це бонус). Моє основне обґрунтування, яке сприяє обгортанню, є простим

Сторонні бібліотеки не розроблені для наших конкретних потреб.

І це проявляється, як правило, у формі завантаження коду, як розробники, які записують 8 рядків коду просто для створення QButtonта стилю його так, як слід шукати додаток, тільки щоб дизайнер хотів не лише виглядати але також функціональність кнопок для повного зміни всього програмного забезпечення, що вимагає повернення та переписування тисяч рядків коду, або виявлення, що для модернізації конвеєра візуалізації потрібне епічне перезаписування, оскільки база коду посипала спеціальні спеціальні низькі рівні трубопровідний код OpenGL всюди, замість того, щоб централізувати дизайн рендерінгу в режимі реального часу і не застосовувати OGL суворо для його реалізації.

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

Звичайно, я застосував би сильні винятки до бібліотек, де обгортки - це майже один на один переклад того, що можуть запропонувати сторонні API. У цьому випадку не може бути розроблений дизайн вищого рівня, який би виразніше виражав вимоги бізнесу та дизайну (такий може бути випадок, що нагадує більше "бібліотеку"). Але якщо є набагато більш пристосований дизайн, який набагато прямо виражає наші потреби, то я сильно перебуваю в обгортковому таборі, так само як я рішуче за те, щоб використовувати функцію вищого рівня та використовувати її над вбудованим кодом складання повсюдно.

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

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


0

Моя ідея про сторонні бібліотеки:

Нещодавно в спільноті iOS було обговорено плюси та мінуси (гаразд, переважно мінуси) використання сторонніх залежностей. Багато аргументів, які я бачив, були досить загальними - групування всіх сторонніх бібліотек в один кошик. Як і у більшості речей, це все не так просто. Отже, спробуємо зосередитись на одному випадку

Чи слід уникати використання сторонніх бібліотек інтерфейсу користувача?

Причини розгляду сторонніх бібліотек:

Здається, є дві основні причини, за якими розробники вважають використання сторонньої бібліотеки:

  1. Відсутність вміння чи знань. Скажімо, ви працюєте над додатком для обміну фотографіями. Ви не починаєте з прокатки власної криптовалюти.
  2. Брак часу або інтересу, щоб щось побудувати. Якщо у вас немає необмеженої кількості часу (якого ще ніхто не мав), ви повинні розставити пріоритети.

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

Якщо це основна функція бізнесу - робіть це самостійно, незалежно від того, що це.

Є майже два типи елементів керування / перегляду:

  1. Загальне, що дозволяє використовувати їх у багатьох різних контекстах, про які навіть не думали їхні творці, наприклад, UICollectionViewвід UIKit.
  2. Конкретний, розроблений для одного випадку використання, наприклад UIPickerView. Більшість сторонніх бібліотек, як правило, належать до другої категорії. Більше того, вони часто витягуються з існуючої бази даних, для якої вони були оптимізовані.

Невідомі ранні припущення

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

Часто вивчення ідеї вигідніше, ніж отримання отриманого коду.

Ви не можете цього приховати

Через те, як створено UIKit, ви, швидше за все, не зможете приховати сторонній бібліотеку інтерфейсу, наприклад, за адаптером. Бібліотека переплететься з вашим кодом інтерфейсу і стане фактичним фактом вашого проекту.

Майбутня вартість часу

UIKit змінюється з кожним випуском iOS. Все зірветься. Залежність від сторонніх організацій не буде такою, що потребує обслуговування, як ви могли очікувати.

Висновок:

З мого особистого досвіду, більшість застосувань сторонніх інтерфейсів користувача зводиться до обміну меншою гнучкістю на деякий час.

Ми використовуємо готовий код для швидшого надсилання поточного випуску. Однак рано чи пізно ми потрапляємо в межі бібліотеки і стоїмо перед важким рішенням: що робити далі?


0

Використання безпосередньо бібліотеки більш дружнє для команди розробників. Коли приєднується новий розробник, він може мати повний досвід роботи з усіма використаними рамками, але не зможе продуктивно зробити свій внесок до того, як вивчити домашній API. Коли молодший розробник намагається просунутися у вашій групі, він буде змушений вивчити ваш конкретний API, який немає ніде більше, замість набуття більш корисної загальної компетенції. Якщо хтось знає корисні функції або можливості оригінального API, він не зможе досягти шару, написаного тим, хто про них не знав. Якщо хтось отримає завдання програмування під час пошуку роботи, він може не зможе продемонструвати основні речі, якими він користувався багато разів, тільки тому, що всі ці часи він отримував доступ до необхідної функціональності через вашу обгортку.

Я думаю, ці питання можуть бути важливішими, ніж досить віддаленою можливістю використання зовсім іншої бібліотеки пізніше. Єдиний випадок, який я використовую обгорткою, - це коли перехід на іншу реалізацію, безумовно, запланований або завершений API недостатньо заморожений і постійно змінюється.

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