Хороший разработчик, с которым я работаю, недавно рассказал мне о некоторых трудностях, с которыми он столкнулся при реализации функции в некотором коде, который мы унаследовали; он сказал, что проблема была в том, что за кодом было трудно следовать. Исходя из этого, я посмотрел вглубь продукта и понял, как трудно было увидеть путь к коду.
Он использовал так много интерфейсов и абстрактных слоев, что пытаться понять, где все начиналось и заканчивалось, было довольно сложно. Это заставило меня задуматься о тех временах, когда я смотрел на прошлые проекты (до того, как я стал настолько осведомлен о принципах чистого кода), и мне было чрезвычайно трудно обойтись в проекте, главным образом потому, что мои инструменты навигации по коду всегда приводили меня к интерфейсу. Потребовалось бы много дополнительных усилий, чтобы найти конкретную реализацию или где что-то было связано с какой-то архитектурой типа плагина.
Я знаю, что некоторые разработчики строго отказываются от контейнеров внедрения зависимостей по этой самой причине. Это настолько запутывает путь программного обеспечения, что сложность навигации по коду увеличивается в геометрической прогрессии.
Мой вопрос: когда фреймворк или шаблон вносит столько накладных расходов, как это, стоит ли это того? Это признак плохо реализованного паттерна?
Я думаю, разработчик должен взглянуть на более широкую картину того, что эти абстракции привносят в проект, чтобы помочь им преодолеть разочарование. Обычно, однако, трудно заставить их увидеть эту общую картину. Я знаю, что мне не удалось продать потребности МОК и ДИ с TDD. Для этих разработчиков использование этих инструментов слишком сильно ограничивает читабельность кода.
источник
Ну, недостаточно абстракции, и ваш код трудно понять, потому что вы не можете изолировать, какие части что делают.
Слишком много абстракции, и вы видите абстракцию, но не сам код, а затем затрудняете выполнение реального потока выполнения.
Чтобы добиться хорошей абстракции, нужно поцеловаться: посмотрите мой ответ на эти вопросы, чтобы знать, что нужно делать, чтобы избежать подобных проблем .
Я думаю, что избегание глубокой иерархии и именования являются наиболее важным моментом, который нужно рассмотреть для описываемого вами случая. Если бы абстракции были хорошо названы, вам не пришлось бы заходить слишком глубоко, только на уровень абстракции, где вы должны понимать, что происходит. Именования позволяют вам определить, где находится этот уровень абстракции.
Проблема возникает в низкоуровневом коде, когда вам действительно нужно понять весь процесс. Тогда инкапсуляция через четко изолированные модули - единственная помощь.
источник
Для меня это проблема сцепления и связана с гранулярностью дизайна. Даже самая слабая форма связи вводит зависимости от одного к другому. Если это делается для сотен или тысяч объектов, даже если все они относительно просты, придерживаются SRP, и даже если все зависимости направлены к стабильным абстракциям, это дает кодовую базу, которую очень трудно рассуждать как взаимосвязанное целое.
Есть практические вещи, которые помогают вам оценить сложность кодовой базы, не часто обсуждаемые в теоретической SE, например, насколько глубоко в стек вызовов вы можете попасть, прежде чем достигнуть конца, и насколько глубоко вам нужно пройти, прежде чем вы сможете, с большая уверенность, понять все возможные побочные эффекты, которые могут возникнуть на этом уровне стека вызовов, в том числе в случае исключения.
И я на собственном опыте обнаружил, что более плоские системы с более мелкими стеками вызовов гораздо легче рассуждать. В качестве крайнего примера можно привести систему объект-компонент, где компоненты - это просто необработанные данные. Функциональность есть только у систем, и в процессе реализации и использования ECS я обнаружил, что это самая простая из когда-либо существовавших систем, когда можно рассуждать о том, когда сложные кодовые базы, охватывающие сотни тысяч строк кода, в основном сводятся к нескольким десяткам систем, которые содержать все функции.
Слишком много вещей обеспечивают функциональность
Альтернативой ранее, когда я работал в предыдущих кодовых базах, была система с сотнями или тысячами в основном крошечных объектов, в отличие от нескольких десятков громоздких систем, в которых некоторые объекты использовались просто для передачи сообщений от одного объекта к другому (
Message
объект, например, который имел собственный публичный интерфейс). Это в основном то, что вы получаете аналогично, когда вы возвращаете ECS обратно к точке, где компоненты имеют функциональные возможности, и каждая уникальная комбинация компонентов в сущности дает свой собственный тип объекта. И это, как правило, приводит к меньшим, более простым функциям, унаследованным и обеспеченным бесконечными комбинациями объектов, которые моделируют крошечные идеи (Particle
объект противPhysics System
например). Тем не менее, он также имеет тенденцию создавать сложный график взаимозависимостей, который затрудняет рассуждение о том, что происходит на широком уровне, просто потому, что в базе кода есть так много вещей, которые действительно могут что-то сделать и, следовательно, могут сделать что-то не так - - типы, которые не являются типами «данных», но являются типами «объектов» со связанной функциональностью. Типы, которые служат чистыми данными без какой-либо связанной функциональности, не могут ошибаться, так как они ничего не могут сделать самостоятельно.Чистые интерфейсы не очень помогают в этой проблеме понятности, потому что даже если это делает «зависимости времени компиляции» менее сложными и предоставляет больше возможностей для изменений и расширений, это не делает «зависимости времени выполнения» и взаимодействия менее сложными. Клиентский объект все еще заканчивается вызовом функций для конкретного объекта учетной записи, даже если они вызываются
IAccount
. Полиморфизм и абстрактные интерфейсы имеют свое применение, но они не разделяют вещи таким образом, который действительно помогает вам размышлять обо всех побочных эффектах, которые могут произойти в любой данный момент. Чтобы добиться такого эффективного разделения, вам нужна кодовая база, в которой гораздо меньше функций, содержащих функциональность.Больше данных, меньше функциональности
Таким образом, я нашел, что подход ECS, даже если вы не применяете его полностью, будет чрезвычайно полезным, поскольку он превращает то, что было бы сотнями объектов, в просто необработанные данные с помощью громоздких систем, более грубо спроектированных, которые обеспечивают все функциональность. Это максимизирует количество типов «данных» и сводит к минимуму количество типов «объектов», и, следовательно, абсолютно минимизирует количество мест в вашей системе, которые могут действительно пойти не так. Конечным результатом является очень «плоская» система без сложного графа зависимостей, только системы с компонентами, никогда не наоборот, и никогда не компоненты с другими компонентами. В основном это гораздо больше необработанных данных и намного меньше абстракций, что приводит к централизации и выравниванию функциональности базы кода для ключевых областей, ключевых абстракций.
30 более простых вещей не обязательно проще рассуждать о чем-то более сложном, если эти 30 более простых вещей взаимосвязаны, а сложная вещь стоит сама по себе. Таким образом, мое предложение состоит в том, чтобы на самом деле перенести сложность от взаимодействий между объектами и больше к более объемным объектам, которым не нужно взаимодействовать с чем-либо еще для достижения массовой развязки, к целым «системам» (не монолитам и объектам бога, учтите, и не классы с 200 методами, но что-то значительно более высокого уровня, чем a
Message
или a,Particle
несмотря на минималистский интерфейс). И предпочитаю более простые старые типы данных. Чем больше вы зависите от них, тем меньше связи вы получите. Даже если это противоречит некоторым идеям SE, я обнаружил, что это очень помогает.источник
Может быть, это симптом выбора неправильного языка программирования.
источник
Плохое понимание шаблонов проектирования, как правило, является основной причиной этой проблемы. Одним из худших, что я видел, когда вы переходили от интерфейса к интерфейсу без большого количества конкретных данных, было расширение для Oracle Grid Control.
Честно говоря, похоже, что у кого-то был мой абстрактный метод фабрики и шаблонный оргазм во всем моем Java-коде. И это заставило меня чувствовать себя таким же пустым и одиноким.
источник
Я бы также предостерег от использования функций IDE, которые упрощают абстрагирование.
источник