Кращі практики для обміну крихітними фрагментами коду між проектами


102

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

Але часто я пишу невеликі методи (можливо, 10 - 15 рядків коду), які потрібно повторно використовувати в двох проектах, які не можуть посилатися один на одного. Метод може бути пов'язаний із мережею / рядками / MVVM тощо. Це загалом корисний метод, не характерний для проекту, в якому він спочатку знаходиться.

Стандартним способом повторного використання цього коду було б створення незалежного проекту для коду для багаторазового використання та посилання на цей проект, коли він вам потрібен. Проблема з цим полягає в тому, що ми опинилися в одному з двох менш ідеальних сценаріїв:

  1. Ми закінчуємо десятками / сотнями крихітних проектів - кожен з яких розміщує маленькі класи / методи, які нам знадобилися для повторного використання. Чи варто створити зовсім новий .DLLлише для крихітного коду?
  2. Ми закінчуємо одним проектом, що містить все більшу колекцію непов'язаних методів та класів. Цей підхід - це те, що робила компанія, в якій я працював; У них був проект, base.commonякий назвав папки для таких речей, як я вже згадував вище: мережа, маніпуляція з рядками, MVVM і т. д. Це було неймовірно зручно, але посилання на нього непотрібно перетягувати з собою весь непотрібний код, який вам не потрібен.

Отже, моє запитання:

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

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


Примітка: Моє використання слів "Проект", "Рішення" та "Довідка" походить з передумови в розробці .NET у Visual Studio. Але я впевнений, що це питання не залежить від мови та платформи.


21
+1, хоча, на мою думку, є елемент гумору у того, хто працює з .NET, переймаючись перетягуванням неактуального коду через посилання на DLL.
JDB

2
@ColeJohnson .NET сам по собі - це величезна довідка! Напевно, набагато більше, ніж у дріллів, які б я зробив сам.
Джордж Пауелл

2
Я це розумію. Однак компілятор JIT JIT завантажує лише необхідні методи в оперативну пам’ять (коли вони викликаються)
Cole Johnson

1
Правда. Хоча вам все-таки доводиться поширювати весь .NET-рамку всім, хто хоче використовувати ваш продукт, а великими проектами та складними рішеннями важче керувати.
Джордж Пауелл

Відповіді:


75

Якщо вони дійсно є багаторазовими методами / класами, ви можете записати їх у невелику кількість бібліотек «Швейцарський армійський ніж». Ми робимо це досить часто в моїй компанії; ми називаємо їх рамковими бібліотеками:

  • Framework.Data - Утиліти для роботи з запитами до бази даних.
  • Framework.ESB - Стандартні методи взаємодії з нашою службовою шиною обслуговування
  • Framework.Logging - Уніфікована система блокування
  • Framework.Services - Утиліти для взаємодії з веб-сервісами
  • Framework.Strings - Утиліти для розширеної маніпуляції з рядками / нечіткого пошуку рядків тощо.
  • ...

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

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


4
+1 Це був би і мій підхід. Цікаво дізнатись, як ви вирішили куди поставити код, який стосується речей з двох чи більше аспектів. Наприклад, IPAddressToString. І чи дозволяєте ви цим бібліотекам використовувати один одного. Наприклад, сервіси та дані, можливо, можуть отримати багато користі від ведення журналу ...
Marjan Venema

5
@MarjanVenema Для наскрізного коду залежить, яким споживачам цей метод стане більш корисним. Бо IPAddressToString, ймовірно, споживачам, які мають мережеві протоколи, доведеться цим користуватися, але споживачі, які роблять багато спірання з рядками, можуть взагалі не піклуватися про IP-адреси. Це, мабуть, закінчиться швидше мережевим пакетом Framework.Strings.
pswg

@MarjanVenema Ми намагаємось уникати взаємозалежностей. Наші служби та рамки даних написані таким чином, що вони не роблять жодного журналу самостійно, але полегшують споживачеві написати правильний код реєстрації. Рамкові бібліотеки дозволяють посилатися один на одного, але лише шляхом розширення - наприклад Framework.Logging.Gibraltar, це певна надбудова до системи реєстрації журналів.
pswg

5
+1 Ви можете взяти ці бібліотеки фреймворку та розгорнути їх у внутрішнє сховище NuGet (просте, як мережева папка), і у вас є хороший спосіб управління ним.
Стівен Еверс

2
@SteveEvers Я зараз працюю над налаштуванням. : P
pswg

21

Я не згоден з прийнятою відповіддю з багатьох причин.

З мого досвіду, коли я бачу "різні" бібліотеки на зразок прийнятої відповіді, вони є приводом винаходити колесо (або не винайдене тут (NIH) ) - набагато більший гріх, ніж порушувати Dont Repeat Yourself (DRY) .

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

Підхід численних бібліотек загального призначення подає поганий приклад. Це призводить до тонкої деталізації збірки і занадто багато збірок - це погано. Нещодавно я скоротив власне підприємство з 24 бібліотек до 6 бібліотек. Це покращило час компіляції з декількох хвилин до ~ 20 секунд. Візуальна студія також повільніше завантажується і менше реагує на більше збірок. Занадто багато бібліотек також призводить до плутанини щодо того, де повинен жити код; віддайте перевагу меншій, простіші правила.

Чому матеріал у .Net Framework недостатньо хороший? Рамка досить велика; багато разів я бачив код, який повторно реалізує речі, які вже існують там. Дійсно переконайтесь, що ваші рамки заповнюють прогалини в рамках .Net і не існують лише з естетичних причин (наприклад, "мені тут не подобається .Net Framework" або, можливо, передчасна оптимізація )

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

Використання стандартизованих технологій (на зразок .Net Framework та популярних сторонніх / відкритих бібліотек) має переваги, які часто перевершують порівняльні технологічні переваги побудови його самостійно. Простіше знайти талант, який знає ці технології, а ваші існуючі розробники вкладуть більше коштів у його вивчення.

Мої рекомендації:

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

1
Перевагою є використання бібліотек з відкритим кодом, коли вони доступні - якщо ви знайдете якісь вдосконалення, ви можете поділитися ними спільнотою! Наприклад,. Всім користь!
Гленатрон

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

Через п'ять років керівництво мікросервісу
Дейв Хіллер

11

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

По-перше, просто спростити код під рукою, особливо під час створення та налагодження матеріалів.

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

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


5
Я не згоден з таким підходом. Я високо ціную проблеми з технічним обслуговуванням при управлінні невеликими фрагментами коду, але я б стверджував, що з усіх них може бути створена якась загальна бібліотека, наприклад @psw. Дублювання копій коду з незначними перетвореннями в ньому задає проблеми. Припущення будуть зроблені, виправлення помилок будуть пропущені.
Ендрю Т Фіннелл

2
-1 (до відповіді). Безумовно, простіше мати кожний власний примірник своїх версій програм. Ось як розроблялося програмне забезпечення у 80-х. З тих пір я дізнався, що - довгостроково - це призводить до безладу. Важче зробити правильно і мати спільну бібліотеку, оскільки людям потім доведеться набагато більше спілкуватися про свою роботу. Ну, вони повинні.
Майкл Дюрант

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

6

Друге описане вами рішення не так вже й погано. У .NET ви також посилаєтесь на збірку з GAC, навіть якщо ви просто використовуєте один клас цього класу. "Перетягування нерелевантного коду" - це не проблема, як ви могли подумати. У цьому випадку важливо хоча б підтримувати пов'язані методи та класи в чистому організованому просторі імен. Крім того, слід застосовувати добрі практики для розробки API, щоб запобігти розтвору цього рішення.

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


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

6

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

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

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


У якому сенсі ви очікуєте, що вони не виявляться? Таким чином ми використовуємо велику кількість зростаючих пакетів. Найбільша проблема, яку ми маємо, - це керування версіями та залежностями.
pdr

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

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

@sarfeast Було б добре, якби ви могли поділитися посиланням на будь-який сервер Nuget і трохи розповісти про це.
Ганс-Пітер Штерр

6

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


5

У GitHub є досить корисний інструмент для збереження фрагментів коду https://gist.github.com/

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


3

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

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

Тоді вам потрібно буде переконатися, що ви знаєте сферу, в якій хочете це зробити. Команда? Проект? Відділ? Компанія? Залежно від відповіді, тип коду, який ви будете вводити в такі рішення, буде різним, як і деталізація, з якою ви підбираєте клітинки. Після того, як ви зважилися на це хтось (бажаючи з деяким захопленням ідеєю - ви?), Слід сісти і почати вносити в це якусь структуру.

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


3

у мене виникло багато проблем, і моїм кращим рішенням є розміщення коду у сховищі веб-сховищ github / pubic. це вирішує багато проблем -

  1. простий доступ і простий доступ у спільний доступ. cvs / svn / enterprise-repos означає перевірку проекту в декілька робочих просторів IDE, а іноді і доводиться перемикати робочі простори або комп'ютери лише для посилання на невеликий фрагмент коду.
  2. якщо припустити, що ці фрагменти коду не є власними / класифікованими фрагментами коду та є варіантами загальнодоступних знань, розміщення їх на публічному репо-сході, як github, означає, що інші будуть дивитись на це і навіть можуть сприяти.
  3. розміщення чогось у відкритому доступі під вашим іменем має додатковий тиск репутації. ви подвоїте перевірку та оновлення речей, оскільки це відображається на ваших здібностях програміста.
  4. оновлення. річ у підтримці фрагментів коду в репо-репері полягає в тому, що якщо фрагмент давно не використовувався, він може старіти (містити застарілі apis / libs). приклад - фрагмент коду Java для читання файлу. ви, можливо, придумали найкращий спосіб зробити це в 2009 році, але в 2014 році вийде новий файл api, який все змінює. ваш фрагмент? все ще застрягли в 2009 році в публічному репо, все буде оновлюватися або вами (бо куля 3), ваші товариші по команді, або хтось із представників загальної програми програміста, і в процесі цього ви навіть можете отримати пропозиції, щоб виправити щось, що ви, можливо, давно робите неправильно.

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


2

У нас є окремий проект "утиліти", де ми зберігаємо всі ці маленькі методи разом з тестами.

Коли проект потребує деякої утиліти, він просто додає вихідний файл необхідним методом із "додати як посилання".

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

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

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


2

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

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


0

Нещодавно я придумав цей сервіс: Snip2Code ( http://www.snip2code.com ).

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

Більше того, існує багато сценаріїв, коли використання загальної бібліотеки просто не застосовується: розглянемо, наприклад, деякі шаблони дизайну, такі як Singleton, Strategy або Observer. Ви можете створити бібліотеки для підтримки таких моделей, але все ще немає 100% охоплення.

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

(Відмова: Я є одним із засновників Snip2Code, і я був разом із моїми співзасновниками - у вашому ж думці: саме тому ми вирішили розпочати цей проект !!)

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