Кроха сын к отцу пришел и спросила кроха: чем же мой код так хорош, ну а что в нем плохо?Ваше приложение работает? Заказчик счастлив? Что ж прекрасно, но это не является показателем качества. Ведь жизнь программного обеспечения не заканчивается после его сдачи. Последующие стадии, такие как поддержка и расширения функционала нельзя считать неважными. Зачастую, при дизайне системы не учитываются некоторые особенности, и это приводит к тому, что программу легче переписать заново, чем модифицировать для удовлетворения новых требований. Какими характеристиками должна обладать система, что бы её можно было назвать хорошо спроектированной, а какими нет, мы рассмотрим далее в этой статье. Что такое плохо.Характеристики системы, которыми она обладать не должна, принято называть «symptoms of poor design». При разработке системы важно обращать на них внимание и следить за тем, что бы они проявляли себя как можно реже. И так, вот они: - Жесткость (Rigidity) – сложно вносить изменения с систему; небольшие изменения требуют серьезных модификаций. «Мне нужно всего лишь добавить новое сообщение на страницу, а я должен переписать пол приложения» - так негодуют разработчики, кому приходится модифицировать «жесткую» систему.
- Хрупкость (Fragility) – даже незначительные изменения, внесенные в систему, могут повлечь за собой непредсказуемые последствия. Обычно такое случается, если код программы не покрыт юнит тестами. В этом случае регрессионное тестирование становится настоящим кошмаром, как для тестеров, так и для разработчиков.
- Неподвижность (Immobility) – тяжело выделить отдельные компоненты для их дальнейшего переиспользования в других системах (компоненты слишком сильно зависят друг от друга). Низкое зацепление и высокое связывание являются тому причиной.
- Вязкость (Viscosity)– делать что-либо правильно сложнее, чем делать неправильно. Типичным примером может быть необходимость «копипастить» вместо наследования или модификация тех же скопированных кусков кода в нескольких местах, вместо внесения одного изменения в общую часть.
- Избыточная сложность (Needless Complexity) – система содержит инфраструктуру без явных преимуществ. Примером может быть создание дополнительных слоев, различных оберток объектов для передачи между этими слоями, хотя можно передавать их напрямую и т.д. Про некоторые решения, которые влекут за собой избыточную сложность, часто говорят: «Стрелять из пушки по воробьям».
- Избыточное повторение (Needless Repetition) – повторяющиеся структуры, которые лучше вынести в общие абстракции. То, что техника «скопировал-вставил» является дурным тоном, известно многим, но, не смотря на это, она применяет достаточно. Как результат система становится хрупкой и вязкой.
- Непрозрачность (Opacity) – тяжело понять что делает код. Чрезмерное использование различных трюков, плюс избыточная сложность, несомненно, приведет к тому, что код станет тяжелым для понимания. Возможно, в трюках и бывает необходимость, но такие участки кода должны быть хорошо документированы. Кроме того, отсутствие корпоративного стандарта по форматированию кода, так же ведет к его непрозрачности.
Что такое хорошо.Обратно характеристикам «бедного дизайна», можно привести те, которые обычно сопровождают дизайн высокого качества: - Минимальная сложность (Minimal complexity) – отсутствие слишком «умного» дизайна. Его всегда сложнее понимать и поддерживать. «Keep it simple» - один из известных принципов Agile разработки.
- Легкость поддержки (Ease of maintenance) – систему легко поддерживать, т.е. легко понять, как она работает и легко модифицировать её логику.
- Низкое связывание (Loose coupling) – система обладает минимальной зависимостью между её компонентами.
- Склонность к расширению (Extensibility) – вы можете легко расширить функционал системы без внесения изменений в существующий код.
- Склонность к повторному использованию (Reusability) – отсутствие повторяющихся кусков кода, высокое зацепление и низкое связывание её компонентов располагает к их легкому повторному использованию в других программах.
- Высокий уровень входящих связей (High fan-in) – один класс часто используется другими классами – это следствие системы, обладающей высоким повторным использованием своих компонентов.
- Низкий уровень исходящих связей (Low-to-medium fan-out) – классы должны зависеть от наименьшего количества других классов. Высокий «fan-out» (более 7) означает, что класс слишком зависим от других классов, что зачастую является следствием его чрезмерной сложности.
- Переносимость (Portability) – программа не испытывает проблем с запуском на других машинах, и при этом, не требует сложной предварительной настройки.
- Худоба (Leanness) – отсутствие неиспользуемых классов и модулей сделает систему более легкой в понимании и поддержке. «You ain't gonna need it», еще один из принципов Agile разработки.
- Расслоение (Stratification) – система, спроектированная по принципу расслоения, легко оценить на каждом уровне без затрат на понимание остальных. Такая фокусировка положительно сказывается как на поиске проблем, так и на способности системы повторному использованию.
- Стандартные подход (Standard techniques) – система полностью написана с использованием единого подхода, таким образом, любой разработчик не испытывает трудностей в понимании частей системы, которые были написаны его коллегами.
Умение отличать хороший код от плохого - это важная способность. Введь не зная маршрута - неизвестно куда приедешь. Ну а я желаю вам не терять ориентир в вопросах качества программного обеспечения. Надеюсь, данная статья была для вас полезна. Удачи!
--------------------
нет времени думать - нужно писать КОД!
|