Як мені подолати параліч за допомогою аналізу при кодуванні?


37

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

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

І тоді, якщо я спробую просто сказати «закрутити, просто зробіть це!», Я вдарив цегляну стіну досить швидко, оскільки мій код не організований, я змішав рівні абстракцій тощо.

Які існують методи / методи для запуску нового проекту, а також створити логічну / модульну структуру, яка буде добре масштабуватися?

- - EDIT - -

Ну, це вже такий тип запитань, на який важко прийняти відповідь, але хотілося отримати ще зворотній зв'язок, подивіться, чи є якийсь консенсус. TDD звучить дуже здорово, і, чесно кажучи, я мав на увазі досягти більшої швидкості використання JUnit і т.д. Конкретні проблеми - це те, що TDD насправді не вирішує питання дизайну. Звичайно, я погоджуюся, що TDD допоможе мені визначити, що я хочу зробити, і тоді я можу поступово працювати над тим, як, але є багато різних загальних моделей / структур дизайну, які можуть пройти через тестування одиниць. Ось тільки це: він тестує окремі UNITS. Я думаю, я трохи розгублений ... я не знаю. Можливо я'

Спасибі!


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

Це чудове питання. Це пастка, в яку я теж потрапив.
Corv1nus

Відповіді:


16

Я рекомендую використовувати Test-Driven-Development , це потребує певного звикання, особливо при роботі з хорошим IDE, таким як затемнення, але переваги великі.

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

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

А також оскільки ви спочатку пишете тест і лише після цього реалізуєте, перед вами є невдалий тест. Тож якщо ви подібні до більшості програмістів, ви не захопитеся шаленим аналізом, оскільки ви подумаєте: «Мені потрібно зробити тестовий твір».

Короткий приклад java:
Скажіть, я хочу розробити програму, яка читає і записує повідомлення з db.

Отже, я починаю з першої чітко визначеної дії, мені потрібна база даних:

@Test
public void testDB() {
  DB db = DbConnector.getDB(address);
  assertNotNull(db);
}

ОК, тому тут я бачу, що мені потрібно реалізувати клас DbConnector.getDB, щоб він повертав БД, до цього часу цей тест не завершився. Я йду і роблю це ...

Чи не я додаю наступне, що хочу зробити, завантажую повідомлення з БД:

@Test
public void testDB() {
  DB db = DbConnector.getDB(address);
  assertNotNull(db);
  String message = db.fetchMessage(key);
  assertEquals("hello world", message);
}

Тепер я додав до БД ще одну невелику функцію, яка полягає в тому, щоб отримати повідомлення, я переходжу та впроваджую це, після закінчення я продовжую переходити одну функцію за один раз, поки не досягну щось подібного:

@Test
public void testDB() {
  DB db = DbConnector.getDB(address);
  assertNotNull(db);
  String message = db.fetchMessage(key);
  assertEquals("hello world", message);
  message = "foo bar";
  db.storeMessage(message);
  message = db.fetchMessage();
  assertEquals("foo bar", message);
}

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


4
І TDD змушує вас перефактурувати багато, тому ви потрапляєте в режим роботи безперервного рефакторингу, який допоможе пробити цегляну стіну зіпсованого коду, як, наприклад, згадували programmers.stackexchange.com/questions/86364/… .
Брод

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

1
@SnOrfus, справа. TDD добре працює, коли ви маєте свої модулі і хочете сконцентруватися на тому, як і як. Але ці модулі можуть бути організовані будь-якою кількістю способів. Як вони згруповані разом, яку структуру ви будете використовувати, насправді не з'ясовується через TDD.
LuxuryMode

5
Гмммм, це звучить як фанат TDD ..... Що коли-небудь траплялося з використанням ручки та паперу для начерки архітектури? або я стара мода і не "стегна" достатньо ....
Darknight

1
Ручка і папір (або дошка) добре. Накресліть загальний план, велику картину. Якщо вона не поміщається на аркуші паперу, це занадто складно. Після того, як ви отримали великий план зображення, ви можете отримати зайняті BDD, насмішка і т.д.
Донал Fellows

10

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

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

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


1
+1 для згадування написання. Я нещодавно прийняв частий підхід від рефакторингу від кодування і застосував його до написання; працює дуже добре для мене.
Zsolt Török

2

Кілька речей, які можуть працювати:

  • Визначте основну проблему, яку ви намагаєтеся вирішити - в чому полягає головна річ, яку ви хочете зробити? Реалізуйте саме це та найменший мінімум коду підтримки, щоб змусити його працювати. Як тільки це спрацює на ваше задоволення, створюйте ітераційно, рефакторинг без милості на кожному кроці.
  • Подивіться, чи працюють для вас інші парадигми програмування. Незважаючи на всі його переваги, об’єктно-орієнтоване програмування - це не відповідь на всі проблеми, і не всі мізки програмістів працюють таким чином. Підберіть (чисту) функціональну мову; написати деякий процесуальний кодекс; зануритися на апаратний рівень і зробити якийсь С або, можливо, навіть асемблер; і т. д. Кілька мов, які можуть похитнути ваш розум (припускаючи, що ви зараз використовуєте щось на зразок C ++ / Java / C # / VB / ...): Haskell, ML, Lisp (різні діалекти на вибір), Erlang, Prolog, Smalltalk, Javascript (якщо ви відмовитеся намагатися змусити його поводитись як Java і замість цього прийняти природу закриття), C, Pascal, awk і, мабуть, ще десяток. Основна особливість полягає в тому, що вони повинні сильно відрізнятися від тих, якими ви зараз користуєтеся. Це не те, що ти хочеш робити у великому проекті з великою кількістю загроз,
  • Використовуйте радикально інший метод дизайну. Подивіться, чи можете ви підібрати дизайн під іншим кутом. Я припускаю, що ви зазвичай починаєте проектувати, розкладаючи свої класи; як щодо початку змін зі структурами даних? А як ви сформулюєте інтерфейс спочатку, буквально малюючи вхідні форми, перш ніж розробляти будь-яку функціональність?

1

Для багатьох дизайнерських рішень це може допомогти зробити «шип», що є коротким, обмеженим у часі дослідницьким зусиллям, де ви можете вивчити деякі архітектури чи варіанти дизайну, кодуючи протокол, що викидається. Наприклад, ви можете вивчити використання якоїсь бібліотеки з відкритим кодом або як ви будете організовувати свої класи та інтерфейси. Їх ключовим є те, щоб він був коротким, щоб ви могли спробувати інший підхід, якщо перший не задовільний, і, сподіваємось, ви отримаєте достатньо знань у вправі для кращого прийняття архітектурних рішень або доведення концепції. Сама вправа передбачає негайне кодування, яке допомагає вийти з "блоку авторів", не обов'язково брати на себе "git 'er done" занадто рано.

Після цього вигідно використовувати підхід TDD або BDD, про який згадував Асаф, щоб продовжувати реалізацію проекту.


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

1

Вам це не знадобиться , тому не думайте занадто багато на початку.

Вкладіть більше часу для визначення, розуміння мети та проблеми.

"Розширення та повторне використання" - це природний результат життєвого циклу добре написаних програмних програм.


0

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

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


0

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

  • Відкладіть свій незайманий проект убік та працюйте над нечіткою версією. Це версія, де ви говорите собі: a. Код не повинен бути гарним. Насправді, скажіть собі, основні рефакторинг та переформатування заборонені. Нехай це буде абсолютно неорганізовано і звільнити себе від зв’язків хорошого кодування. б. Це просто має працювати. c. Мене завжди дивує те, що я дізнаюся про проблемний простір, коли викидаю всі інші проблеми. Я також закінчую маленькими ласощами, які часто допомагають мені підійти до правильного дизайну в більш освіченому вигляді.

  • Відкладіть пристойний розмір часу, де ви працюєте над проектом, лише без комп’ютера. Спробуйте осмислити те, що ви насправді намагаєтеся виконати, і шукайте той магічний дзен, який перевершує безумство OO / Design Pattern.


0

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

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


0

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

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

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