Конкретные симптомы чрезмерной инженерии [закрыто]

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

Это первое" производственное " приложение, которое я написал, у него есть 45k Loc, и я потратил на него почти два года "сольной" разработки. Я довольно молод (18) и написал приложение с нуля, будучи заключенным в качестве дублера для бывшего разработчика, который оставил компания. Не имея опыта в разработке приложений такого размера, я попытался использовать общие шаблоны архитектуры и дизайна.

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

оба кандидата имеют 10 лет+ фон в разработке внутренних приложений с соответствующими платформа. Будучи вдвое моложе их и имея мало опыта, я уважаю их мнение. Когда я объяснял им архитектуру приложения, комментарии были примерно такими:

  • Боже, никто бы не заплатил мне, чтобы я делал такие вещи, я должен делать вещи
  • придерживайтесь того, что делает фреймворк, не используйте причудливые библиотеки/технологии
  • не обертывать код фреймворка. В команде каждый напишет свой собственный код оболочки в любом случае.
  • вы используете .NET 3.5? Ну, мы используем 2.0.
  • что это LINQ вещи купить мне? Вся эта композиция запросов и проекция кажется слишком сложной.

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

17 ответов


каковы симптомы чрезмерная инженерия?

код, который решает проблемы у вас нет.


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


скука

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

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

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

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


написание собственной структуры

скорее всего, кто-то уже сделал это. Более того, они уже сделали это в 1000 раз лучше чем ты. Более того, то, что они сделали, вероятно, уже является отраслевым стандартом, так что изучение технологии сделает вас более конкурентоспособными на других работах.

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

Он написал свою собственную структуру инъекций зависимостей, свой собственный ORM, структуру модульного тестирования (которая, необъяснимо, выглядела и действовала очень похоже на NUnit-почему он не использовал NUnit?), фреймворк для создания заводских объектов (a"фабрики" Я бы назвал это).

имейте в виду, код был на самом деле замечательно, но какой в этом смысл?

написание лучшей основной библиотеки

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

между прочим, они написали:

  • платформа active-directory для проверки подлинности форм в ASP.NET webforms -- необъяснимо, потому что ASP.NET имеет эту функцию встроенный.
  • горячая замена темы и скины для веб-сайтов - также необъяснимо, так как код был менее функциональным, чем встроенный ASP.NET темы и требуется 1000% больше раздувать.
  • они необъяснимо написали свои собственные типизированные наборы данных и адаптеры данных. Эти объекты обеспечивают меньшую функциональность, чем типизированные наборы данных, которые VS будет автогенерировать для вас, одновременно требуя больше шаблонного кода, чем объекты домена NHibernate.

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

есть только несколько примеров, которые я могу придумать, где повторно реализованная библиотека лучше, чем оригинал (см. Библиотека Ядра Джейн Стрит, общие коллекции C5 для .NET,реальный класс валюты), но, скорее всего, вы не напишете лучшую стандартную библиотеку.


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

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

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


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


IMHO большинство комментариев, которые вы получили о своем приложении, на самом деле не о чрезмерной инженерии, потому что чрезмерная инженерия-это не технология. Речь идет об архитектуре. Новые технологии могут быть изучены и поняты в разумные сроки. Понимание чрезмерно спроектированного приложения обычно намного сложнее, а иногда даже невозможно. Это делает пункты 2, 4 и 5 недействительными. Первый пункт не действительно действителен, потому что вам, очевидно, заплатили за написание приложение как есть и если он работает у вас здесь нет проблем.

Это мой "быстрый тест", чтобы узнать, если приложение как правило быть сверх-проектированным:

  • обертки для "всего": обертки полезны, но это легко переусердствовать. Проверьте, если вы только обернуть вещи, которые действительно должны быть обернуты. (Я в основном обернул свою собственную обертку один раз. Я знаю, о чем говорю ;-) .)
  • изобретение колеса: A классический. Это очень распространено, и вы уже упоминали об этом. Вы реализовали некоторые функции, потому что вы нужны на хотел to? Что делает ваша платформа, чего не делают другие доступные библиотеки?
  • "чувствует" переусложненный: Это самый важный момент, но и самый трудный момент, чтобы увидеть. Взгляните на свой код и посмотрите, какие части кажутся слишком сложными. Спросите себя, есть ли более простой способ реализовать его и почему ты не выбрала этот путь. Если у вас нет хорошего ответа, эта часть, вероятно, чрезмерно спроектирована.

Это просто быстрые советы, которые я использую для моего приложения. Они не гарантированы, что будут be-all и end-all "обнаружения над-инженерства".


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


избегая любого применения YAGNI, сухой и поцелуй приходите на ум, глядя на вещи, которые чрезмерно спроектированы. Если есть много частей, которые кажутся частично завершенными, и многие части кода, которые, похоже ,имеют: "что, если это произойдет? Что, если это случится?- почувствуй, это было бы совсем другое дело. Игнорирование хорошие принципы дизайна ОО или твердые принципы было бы еще одно замечание. Если вы думаете, что написанный идеальный код был бы еще одним признаком проблемы, так как крайне редко кто-либо пишет то, что не может быть улучшено тем или иным способом.

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


плагины, которые обеспечивают внутреннюю функциональность вашего приложения

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

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

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


вы не астронавт архитектуры. LINQ довольно прост, прост и полезен для одного. То же самое касается .NET 3.5.

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

возьмите все это с солью. Просто примите их критику, кивните, а потом выпейте с ними пива.

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


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

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

В дополнение, различные применения требуют различных amouhts инженерства. Это приложение будет стоить жизни, если это не удастся? Т. е. это контроллер для механического сердца или для навигационных ракет космического челнока? Или это список контактов для скучающих подростков?


на более общем и высоком уровне подхода,

I feel that when there's a gap between the complexity of the problem and
the complexity of the solution, then you have a clear case of overengineering. 

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


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

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


половина из них-старики (я в их Лиге), придерживающиеся испытанного и истинного парового двигателя, который они знали. другая половина правдива, но не говорит вам ничего нового.

кроме этого, ответа Джефф грудины является звездной.


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

в" старые " дни, недо-Инжиниринг был распространен, что привело ко всем структурированным методологиям и практикам. Теперь, кажется, мы пошли другим путем. Нет простого ответа, и иногда вы будете знать только, если вы под или над проектированным в задним числом ;)

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

Мне еще предстоит выделить абсолютные правила для совершения звонка...

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


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

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

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

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

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