Как мне преодолеть паралич с помощью анализа при кодировании?

37

Когда я начинаю новый проект, я часто сразу начинаю думать о деталях реализации. «Где я собираюсь поместить DataBaseHandler? Как я должен его использовать? Должны ли классы, которые хотят его использовать, выходить из какого-то абстрактного суперкласса? .. Должен ли я использовать интерфейс? Какой уровень абстракции я собираюсь использовать в своем классе, который содержит методы отправки запросов и анализа данных?

Я заканчиваю тем, что остановился в течение долгого времени, потому что я хочу закодировать для расширяемости и возможности повторного использования. Но я чувствую, что почти невозможно забыть о том, как реализовать идеально.

И потом, если я попытаюсь просто сказать «винт это, просто сделай это!», Я довольно быстро ударился о кирпичную стену, потому что мой код не организован, я смешал уровни абстракций и т. Д.

Какие у вас есть методы / методы для запуска в новом проекте, а также для настройки логической / модульной структуры, которая будет хорошо масштабироваться?

- - РЕДАКТИРОВАТЬ - -

Ну, это уже тот тип вопроса, на который трудно принять ответ, но он хотел получить больше отзывов, посмотреть, есть ли какой-то консенсус. TDD звучит очень круто, и, честно говоря, я намеревался научиться использовать JUnit и т. Д. В то же время, что думают фанаты TDD о том, что одна законная точка в отношении TDD решает мою проблему? Особые проблемы заключаются в том, что TDD на самом деле не решает вопрос дизайна. Конечно, я согласен с тем, что TDD поможет мне определить, что я хочу делать, и затем я смогу постепенно проработать «как», но есть много различных общих шаблонов / структур проектирования, которые все могут пройти модульное тестирование. Вот и все: он тестирует отдельные ЕДИНИЦЫ. Я думаю, я немного смущен ... Я не знаю. Может я'

Благодарность!

LuxuryMode
источник
2
Отойдите, возьмите ручку и бумагу, нарисуйте большую картину. это поможет вам спроектировать реализацию более структурированным способом, а не потерять себя в деталях ...
Darknight
Это большой вопрос. Это ловушка, в которой я тоже виноват.
Corv1nus

Ответы:

16

Я рекомендую использовать Test-Driven-Development , это требует некоторого привыкания, особенно при работе с хорошей IDE, такой как eclipse, но преимущества велики.

По сути, вы пишете тесты в свой код, прежде чем писать сам код. Таким образом, вы вынуждены смотреть на свой код с точки зрения того, как он будет использоваться, что означает, что ваши интерфейсы будут развиваться по мере развития сценариев.

Другая особенность заключается в том, что вы реализуете очень маленькими порциями (они становятся больше по мере того, как вы разбираетесь в технике и программировании), поэтому вам приходится каждый раз фокусироваться на очень маленькой и четко определенной проблеме.

Кроме того, поскольку вы сначала пишете тест, а затем внедряете его, у вас есть неудачный тест. Поэтому, если вы похожи на большинство программистов, вы не будете увлечены сумасшедшим анализом, потому что вы будете думать: «Мне нужно, чтобы этот тест работал».

Краткий пример Java:
скажем, я хочу разработать программу, которая читает и пишет сообщение из БД.

Итак, я начинаю с первого четко определенного действия, мне нужна БД:

@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, издевательством и т. Д.
Donal Fellows
10

Это происходит со мной, поэтому я привык принимать (и принимать) образ мыслей постоянного рефакторинга. Я делаю простейшую вещь, которая могла бы сработать, затем я очищаю ее, организовываю, разделяю, проверяю и иду дальше.

Нельзя сказать, что не так много планирования, но это происходит очень быстро и чаще, как каракули на металлоломе или в моей голове. В общем, я иногда называю это маленькими процессами микро-итераций, потому что они занимают 5-20 минут каждая, а из опыта требуется 2-3, чтобы закончить то, над чем я работаю (очевидно, в зависимости от того, что я делаю).

В качестве дополнительного примечания: я обучал множество людей различным формам письма (отчеты, эссе и техническое письмо в целом), и это так же, как я заставляю их писать вещи, чтобы преодолеть блок писателя. «Просто выпустите что-нибудь о своей теме, которая придет вам в голову, на страницу. Тогда мы разберемся с этим, разделим все на абзацы и проверим последовательность действий. Если потребуется, мы даже перепишем это».

Стивен Эверс
источник
1
+1 за упоминание письма. Я только недавно принял подход частого рефакторинга от кодирования и применил его к письму; работает очень хорошо для меня.
Жолт Тёрёк
2

Несколько вещей, которые могут работать:

  • Определите основную проблему, которую вы пытаетесь решить - какова суть того, что вы хотите сделать? Реализуйте только это и необходимый минимум кода поддержки, чтобы он работал. Как только это сработает к вашему удовольствию, создавайте итеративно, без всякой жалости на каждом этапе.
  • Посмотрите, работают ли другие парадигмы программирования для вас. Несмотря на все свои достоинства, объектно-ориентированное программирование не является решением всех проблем, и не все мозги программистов работают таким образом. Подобрать (чистый) функциональный язык; написать некоторый процедурный код; нырнуть до уровня оборудования и сделать немного C или даже ассемблер; и т. д. Несколько языков, которые могут вас расшевелить (если вы сейчас используете что-то вроде C ++ / Java / C # / VB / ...): Haskell, ML, Lisp (различные диалекты на выбор), Erlang, Prolog, Smalltalk, Javascript (если вы отпустите попытку заставить его вести себя как Java и вместо этого использовать его закрытую природу), C, Pascal, awk и, вероятно, еще десяток. Ключевая особенность в том, что они должны сильно отличаться от того, что вы используете сейчас. Это не то, что вы хотите сделать в большом проекте с большим количеством ставок,
  • Используйте совершенно другой метод проектирования. Посмотрите, сможете ли вы подобрать дизайн под другим углом. Я предполагаю, что вы обычно начинаете проектировать, выкладывая свои классы; как насчет того, чтобы начать со структур данных для изменения? Или как насчет того, чтобы сначала спроектировать пользовательский интерфейс, буквально рисуя формы ввода, прежде чем разрабатывать какую-либо функциональность?
tdammers
источник
1

Для многих проектных решений это может помочь сделать «всплеск», который является коротким, ограниченным во времени исследовательским усилием, где вы можете исследовать некоторые варианты архитектуры или дизайна, кодируя одноразовый прототип. Например, вы могли бы изучить использование некоторой библиотеки с открытым исходным кодом или как вы будете организовывать свои классы и интерфейсы. Они должны быть краткими, чтобы вы могли попробовать другой подход, если первый неудовлетворительный, и, надеюсь, вы получите достаточно знаний в упражнении, чтобы лучше принимать архитектурные решения или подтверждать концепцию. Само упражнение включает в себя немедленное кодирование, которое помогает выбраться из «блока писателей», не делая обязательных обязательств по «выполнению задания» слишком рано.

После этого выгодно использовать подход TDD или BDD, о котором упоминал Асаф, для продолжения реализации проекта.

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

Вам это не понадобится , так что не думайте слишком много в начале.

Инвестируйте больше времени, чтобы определить, понять цель и проблему.

«Расширяемость и возможность повторного использования» является естественным результатом жизненного цикла хорошо написанных программ.

9dan
источник
0

Я предполагаю, что мы смотрим на проект среднего размера.
Я бы начал с того, что пошел на чертежную доску. Вы должны подготовить свои функциональные и нефункциональные требования, прежде чем сделать это. Сначала вы придумаете архитектуру программного обеспечения, то есть посмотрите на любые архитектурные шаблоны, которые будут соответствовать вашим требованиям.
Как только вы определитесь с тем, как выглядит ваша архитектура, вы должны перейти к низкоуровневому дизайну, то есть взглянуть на все объекты, классы и функциональные возможности. , Здесь вы снова попытаетесь определить подходящие шаблоны проектирования. В процессе вы узнаете, какие у вас базовые классы, и какие интерфейсы вам понадобятся.
Затем вы можете построить фреймворк и выполнить несколько быстрых тестов, чтобы убедиться, что это так. удовлетворяет всем вашим нефункциональным требованиям
Затем я бы пошел с Test Driven Development, как предложил @Asaf.

Помните, несмотря на то, что вы уделяете много времени дизайну и архитектуре, всегда будьте готовы пересмотреть архитектуру, если возникнет такая необходимость.

hangar18
источник
0

Я думаю, что это отличный вопрос, и ничто не будет работать для всех. Я действительно считаю, что такой паралич является естественным побочным продуктом становления все более и более компетентным в своей области. Тем не менее, вот несколько вещей, которые я помогаю, но не решаю проблему:

  • Отложите свой нетронутый проект в сторону и работайте над ошибочной версией. Это версия, где вы говорите себе: Код не должен быть красивым. На самом деле, скажите себе, серьезный рефакторинг и переформатирование не допускаются. Пусть он будет абсолютно неорганизованным и освободит себя от уз хорошего кодирования. б. Это просто должно работать. с. Мне всегда удивительно, что я узнаю о проблемном пространстве, когда отбрасываю все другие проблемы. Я также получаю маленькие лакомые кусочки, которые часто помогают мне прийти к правильному дизайну более просвещенным способом.

  • Выделите приличный размер времени, когда вы находитесь в проекте, просто без компьютера. Попытайтесь осмыслить то, что вы действительно пытаетесь достичь, и найдите тот магический дзен, который выходит за рамки безумия OO / Design Pattern.

Кевин Хсу
источник
0

Дайте конкретное выражение своим мыслям: запишите / напечатайте их, нарисуйте их или что-то еще. Это поможет вам пересмотреть ваши мысли, когда это необходимо; это помешает вам ходить по кругу; поможет вам мыслить более четко.

Всякий раз, когда я вижу, что иду никуда и всюду думаю о чем-то, я набираю их, и это помогает мне мыслить ясно.

Srisa
источник
0

Я обычно начинаю с нуля, создаю самый простой прототип и запускаю что-то. Используйте прототип для обратного проектирования тестовых примеров «счастливого пути», тестовых сценариев для управления интерфейсами, а затем подумайте о предварительных / постконтрактных контрактах, чтобы помочь в создании покрытия тестами.

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

sbrenton
источник