Подтвердить что ты не робот

Как сохранить мой код простым?

- EDIT -

Я считаю, что это правильный вопрос, который может иметь несколько ответов (как определено здесь). Это НЕ дискуссия и опрос. Более того, этот вопрос, по-видимому, НЕ аргументирован, так как ни один из респондентов пока не спорит друг с другом.

- ОРИГИНАЛЬНЫЙ ТЕКСТ -

Потрясающе! Я занимаюсь программным обеспечением около 15 лет, и я до сих пор не знаю, что я делаю:)

Серьезно, я все еще борюсь с основами:
  • overengineering против YAGNI
  • срезающие углы, чтобы соответствовать сроку и оттоку назад.
  • рискованные инновации против скучных добрых вещей
  • наслаждаясь свободой работы в одиночку против силы команды.

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

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

Каждое изменение требует существенного рефакторинга. Если другой человек открыл мой код с целью добавления функции, ему нужно было сделать что-то глупое. Он никак не мог сделать это ПРАВО, даже если он был ГЕНИЙ, даже если бы он был моим собственным CLONE, незнакомым с кодовой базой. Почему, почему ради Бога это происходит? Разве нет какой-то методологии, какой-то технологии, какой-то медитационной техники, что-нибудь вообще?!

Как сохранить мой код простым?

4b9b3361

Ответ 1

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

К простоте... TDD подробно упомянуто, полностью согласен. TDD - это трюк, чтобы держать код сфокусированным на том, что ему нужно делать, и не больше. Часто упоминается рефактор. Полностью согласен.

О простоте и сложности и работе в одиночку... не работайте в одиночку при отправке кода. Получайте обзоры кодов при каждой проверке и призывайте рецензентов кодов обмануть вас за углями. Это будет держать вас в курсе, чтобы сделать правильные компромиссы и балансы. Поговорите с кем-то о своем коде не реже одного раза в день. Поверните рецензентов. Моя работа более ясна и лучше с товарищем по команде. Не волнует, насколько они зеленые. На самом деле, тем лучше, чтобы обеспечить четкий код.

При работе в одиночку... Работа в одиночестве занимает свое место в R & D, а не отправлен код. В лучшем случае одинокие проекты ковбоев делают классные вещи, которые ужасная боль для поддержания. Работа, выполняемая сама по себе, всегда нуждается в месячном или двух повторном внедрении и перекомпоновке в код, поддерживаемый смертными, и исправление нескольких огромных оплошностей. Это действительно очень больно, если этот месяц или два попадания вы после того, как вы отправили ковбойский код.

Изменить: со стороны деталей я нашел различные книги по разработке Drive Drive чрезвычайно полезными в предоставлении способов создания супер-чистого кода. Однако DDD не применим к каждой проблеме.

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

Ответ 2

Как @neodymium указывает на зенитный стиль, не позволяйте вашим алгоритмам управлять кодом. Чтобы проиллюстрировать то, что на самом деле означает рассмотреть следующие преподношения в С#, которые вы написали неделю назад:

public void DoArray(string[] strArr) {
    string s = null;

    for(int i = 0; i < strArr.Length; i++)
    {
        if(strArr[i].Equals("Needle"))
            s = strArr[i];
    }

    if(s != null)
        Console.WriteLine("I've found " + s);
}   

Может потребоваться некоторое время, чтобы узнать, что вы написали, просто взглянув на ваш код. Но в конце вы помните, что этот метод ищет "иглу" в массиве строк. Вы восхищаетесь тем, насколько изобретателен ваш алгоритм, но беспокоитесь о том, что вам понадобилось минуту или две, чтобы понять, что он делает.

Не начинайте делать все ясно, комментируя!

Ваш первый инстинкт может заключаться в том, чтобы писать комментарии, чтобы помочь вашим работающим товарищам, НО СТОП ПРАВИЛЬНО! Комментарии - это только извинение. Вместо этого давайте проясним код... кристально чистый.

Чтобы сделать это, попробуйте подумать, как будто вы никогда не видели свой собственный код раньше. Заставьте это, сказав что-то себе: "что это" и "почему это". И тогда мы начнем реорганизовывать эту вещь. Первый простой рефактор, который мы можем сделать, - это переименовать метод в нечто более подходящее. Как насчет:

public void FindNeedle(string[] strArr) { … }

Что еще мы можем сделать? Мы могли бы:

  • Переименуйте strArr в нечто более подходящее, например haystack.
  • Измените тип возврата на bool и измените метод, чтобы он возвращался при обнаружении иглы.
  • Переместите часть Console.WriteLine(…) метода вне контекста этого метода, чтобы вызывающий код мог сделать это следующим образом: if ( FindNeedle(myArray) ) WriteFoundNeedle();
  • Используйте foreach вместо for.

Код может закончиться следующим образом (ваше перемещение может меняться):

public bool HasNeedle(string[] haystack) {
    foreach(string straw in haystack)
    {
        if(straw.Equals("Needle"))
            return true;
    }
    return false;
}

// Is called by the following:
if ( HasNeedle(strArr) )
{
    Console.WriteLine("I've found the needle!");
}

Рефакторинг с небольшими шагами

Можно сделать много вещей, чтобы сделать ваш код более понятным, понятным и читаемым, и это достигается путем реорганизации вашего кода. Сделайте свои рефакторинги как можно малыми шагами. Подобно перемещению или инкапсуляции логики и присвоению им чего-то гораздо более логичного и читаемого. Что-то простое, как длинный и запутанный if-statement:

if ( strArr[pos - 1].Equals("do") && strArr[pos + 1].Equals("then") )

... можно переделать в нечто более простое, переместив логический оператор в собственный метод:

if ( CurrentIsSurroundedByDoThen(strArr, pos) )

Существует много способов рефакторинга. Я предлагаю вам прочитать некоторые из них, Мартин Фаулер написал книгу об этом, но есть также он-лайн каталог, доступный с образцами кода и/или классом диаграммы. Выбор того, какой рефакторинг вы должны делать или нет, должен решаться в предположении, что он сделает ваш код более поддерживаемым, чем раньше.

В добавлении

Помните, сохраняйте свои рефакторинги просто и делайте это с SOLID принципы в виду.

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

Ответ 3

Как сохранить код простым?

Используйте код для реализации правильных алгоритмов.

Не позволяйте вашим алгоритмам писать код.

Ответ 4

Для меня, Test Driven Development имеет значение. Когда я пишу код без проверки, оправдывая его, я думаю о слишком многих сценариях, беспокоюсь, будет ли код работать, писать много лишних вещей, чтобы убедиться, что он будет работать и т.д.

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

Еще одна вещь, которую я нахожу, - это проверить код проектов с открытым исходным кодом. Многие из них имеют код, который другим легко понять и изменить, поэтому он дает хорошее представление о том, как этого достичь. Одним из моих фаворитов в этом отношении является JMock.

Ответ 5

Один из самых простых и мой любимый - ввести объясняющие переменные.

Это:

if ( (platform.toUpperCase().indexOf("MAC") > -1) &&
      (browser.toUpperCase().indexOf("IE") > -1) &&
       wasInitialized() && resize > 0 )
 {
   // do something
 }

становится:

final boolean isMacOs     = platform.toUpperCase().indexOf("MAC") > -1;
final boolean isIEBrowser = browser.toUpperCase().indexOf("IE")  > -1;
final boolean wasResized  = resize > 0;

if (isMacOs && isIEBrowser && wasInitialized() && wasResized)
{
    // do something
}

Ответ 6

Рефакторинг часто.

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

Ответ 7

Более или менее проверяемое устройство означает, что оно не может быть проверено блоком.:)

Если вы не можете легко написать тест, не перескакивая через множество обручей или работы по настройке, то это, похоже, проблема, IMO и требует рефакторинга.

Я стараюсь следовать трем принципам: Сделай так, чтоб это работало Сделать это правильно Сделайте это быстро.

Во-первых, это просто заставить его работать, в основном тестировать единицы.:)

Затем я реорганизую и улучшаю модульные тесты, завершаю их. Это следующий шаг, на который вы должны пойти, поскольку это звучит так, будто вы можете игнорировать эту концепцию. Кроме того, попробуйте удалить любые жестко заданные значения, чтобы сделать его более гибким. Поместите их в xml файлы, базу данных или как константы в некоторый общий файл.

Затем я профилю и оптимизирую узкие места.

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

Ответ 8

Обычно я использую эту цитату.

Бритва Оккама Самое простое (объяснение | решение), как правило, самое лучшее.

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

Ответ 9

Когда вы планируете добавить или удалить что-либо, спросите себя, принадлежит ли оно 20% усилий, которые обеспечивают 80% разницы.

Если это не так, или вы сомневаетесь, удалите его. Если то, что удалено, важно, оно скоро станет очевидным.

Сохранение того, что вы говорите себе "сделайте это просто", также помогает. Пойдите для простоты и забудьте о коррекции, и придет коррекция, и ПОБЕДИТЕ вас.

Ответ 10

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

Я пытаюсь следовать DRY и KISS. "Не повторяй себя" и "Держи его просто глупо". Я также придерживаюсь правила "одна вещь". Метод, класс, пространство имен должны делать только одно.

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

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

Это действительно смутный вопрос, я согласен, сообщество wiki!

p.s. Я не верю, что что-то есть more или less, это либо is, либо оно isn't

Ответ 11

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

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

Я действительно думаю, что ответ реорганизует большую часть вашей жизни и дисциплинирует его. (Мне тоже нужно!) Подобные проблемы... Я думаю, что большинство из нас в этой лодке.)

Ответ 12

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

Ответ 13

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

Я знаю, что эти показатели грубые. Что действительно важно, так это субъективный психологический опыт сложности, а не номер сложности МакКейба, а последний - грубое приближение к первому. С другой стороны, я нашел эти показатели очень полезными.

Ответ 14

В теме KISS:

1) Не чувствуйте, что вы должны исправить все крошечные ошибки/функции в вашем основном коде. Иногда лучше просто оставить их задокументированными и позволить парню, вызывающему ваш код, беспокоиться о том, как обойти их. (Возможно, у него будет хороший шанс, что он никогда не вызовет эту ошибку, так что любые проверки были бы пустой тратой обработки.) Это позволяет вашему коду быть маленьким, быстрым и простым. Если вы хотите сделать надежную, но раздутую версию, пропишите ее отдельно (поверх) кода библиотеки...

2) Не позволяйте другому парню менять свой код! Он может называть ваш код, или он может расширять ваш код, поэтому, если он уже выполняет свою работу, действительно ли ему нужно изменить ядро? Не позволяйте ему превращать вашу SimpleAndSpeedySearchPage в SuperAdvancedSearchPageWithCowbell, заставляйте его создавать SuperAdvancedSearchPageWithCowbell путем расширения или вызова вашего кода.

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

Резюме: как только ваш код выполняет свою основную работу, перестаньте работать над ним и сделайте его доступным только для чтения! Если вы хотите добавить "расширенные функции" и "исправления, специфичные для вашего приложения", добавьте их в другое место. 100 простых классов лучше, чем 10 раздутых классов.

Ответ 15

Несколько вещей, которые приходят на ум:

  • Постарайтесь заранее планировать свою стратегию реализации - возможно, на бумаге или обсуждать с партнером, прежде чем погрузиться в реализацию. Вероятно, что для обработки частей вашей проблемы уже есть функции библиотеки.
  • Запишите псевдокод, который описывает шаги вашей реализации.
  • Попробуйте реализовать методы, чтобы каждый метод имел одну цель или связывал другие методы. Должно быть возможно сразу увидеть, что должен делать какой-либо метод. Здесь TDD может помочь вам сосредоточиться на небольших методах, которые легче тестировать. Меньшие методы также имеют конкретные имена, поэтому имя уже много говорит вам. Кроме того, некоторые простые показатели сложности, такие как этот вопрос, могут помочь вам определить, пытаются ли ваши методы сделать слишком много.
  • Не останавливайтесь, когда ваша реализация работает - попробуйте реорганизовать до тех пор, пока она не станет как можно более простой. Всегда спрашивайте себя, если кто-то еще читает это, понимают ли они это?