Мне нравится SOLID, и я стараюсь изо всех сил использовать и применять его при разработке. Но я не могу не чувствовать, что подход SOLID превращает ваш код в код «фреймворка» - то есть код, который вы разработали бы, если бы создавали фреймворк или библиотеку для использования другими разработчиками.
Я обычно практиковал 2 режима программирования - создание более или менее точно того, что задают с помощью требований и KISS (типичное программирование), или создание очень общей и многократно используемой логики, сервисов и т. Д., Которые обеспечивают гибкость, которая может понадобиться другим разработчикам (программирование фреймворка) ,
Если пользователь действительно просто хочет, чтобы приложение делало x и y, имеет ли смысл следовать SOLID и добавлять целую кучу точек входа абстракции, когда вы даже не знаете, является ли это допустимой проблемой для начала с участием? Если вы добавляете эти точки входа абстракции, действительно ли вы удовлетворяете требованиям пользователей, или вы создаете инфраструктуру поверх существующей инфраструктуры и стека технологий, чтобы облегчить будущие добавления? В каком случае вы служите интересам заказчика или разработчика?
Это то, что кажется распространенным в мире Java Enterprise, когда кажется, что вы разрабатываете свою собственную среду на основе J2EE или Spring, так что это лучший UX для разработчика, вместо того, чтобы сосредоточиться на UX для пользователя?
источник
Ответы:
Ваши наблюдения верны, принципы SOLID ИМХО сделаны с учетом возможности многократного использования библиотек или фреймворка. Когда вы просто слепо следите за ними, не спрашивая, имеет ли это смысл или нет, вы рискуете чрезмерно обобщать и вкладывать в свою систему гораздо больше усилий, чем, вероятно, необходимо.
Это компромисс, и ему нужен некоторый опыт для принятия правильных решений о том, когда обобщать, а когда нет. Возможный подход к этому состоит в том, чтобы придерживаться принципа YAGNI - не делайте ваш код SOLID «на всякий случай» - или, если использовать ваши слова: не
вместо этого обеспечьте гибкость, в которой действительно нуждаются другие разработчики, как только им это понадобится , но не раньше.
Поэтому, когда у вас есть одна функция или класс в вашем коде, вы не уверены, что она может быть повторно использована, не помещайте ее в ваш фреймворк прямо сейчас. Подождите, пока у вас не появится фактический случай для повторного использования и рефакторинг для «SOLID достаточно для этого случая». Не реализуйте больше настраиваемости (следуя OCP) или точек входа абстракции (используя DIP) в такой класс, который вам действительно нужен для случая повторного использования. Добавьте следующую гибкость, когда на самом деле есть следующее требование для повторного использования.
Конечно, этот способ работы всегда будет требовать некоторого рефакторинга в существующей, работающей кодовой базе. Вот почему автоматические тесты здесь важны. Поэтому с самого начала сделать ваш код достаточно твердым, чтобы его можно было тестировать на уровне модулей, - это не пустая трата времени, и это не противоречит YAGNI. Автоматические тесты являются допустимым случаем «повторного использования кода», так как рассматриваемый код используется как из производственного кода, так и из тестов. Но имейте в виду, просто добавьте гибкость, которая вам действительно нужна для того, чтобы тесты работали, не меньше и не больше.
Это на самом деле старая мудрость. Задолго до того, как термин SOLID стал популярным, кто-то сказал мне, прежде чем мы попытаемся написать код, пригодный для повторного использования, мы должны написать код, пригодный для использования . И я все еще думаю, что это хорошая рекомендация.
источник
Исходя из моего опыта, при написании приложения у вас есть три варианта:
В первом случае обычно получается тесно связанный код, в котором отсутствуют модульные тесты. Конечно, это быстро написать, но это трудно проверить. И это настоящая королевская боль, чтобы измениться позже, когда изменятся требования.
Во втором случае огромное количество времени уходит на то, чтобы предвидеть будущие потребности. И слишком часто эти ожидаемые будущие требования никогда не сбываются. Это похоже на сценарий, который вы описываете. Большую часть времени это пустая трата усилий, что приводит к излишне сложному коду, который все еще трудно изменить, когда появляется требование, которое не ожидалось.
Последний случай, на мой взгляд, является целью. Используйте TDD или аналогичные методы для тестирования кода на ходу, и вы получите слабосвязанный код, который легко изменить, но при этом быстро написать. И дело в том, что, делая это, вы, естественно, следуете многим принципам SOLID: небольшие классы и функции; интерфейсы и внедренные зависимости. И миссис Лисков, как правило, тоже довольна, поскольку простые классы с одиночными обязанностями редко нарушают ее принцип замещения.
Единственный аспект SOLID, который на самом деле здесь не применим, - это принцип открытия / закрытия. Для библиотек и фреймворков это важно. Для автономного приложения не так уж и много. На самом деле это случай написания кода, который следует за « SLID »: легко писать (и читать), легко тестировать и легко обслуживать.
источник
Перспектива, которую вы имеете, может быть искажена личным опытом. Это скользкий наклон фактов, которые по отдельности верны, но в результате этого нет, хотя на первый взгляд это выглядит правильно.
Это означает, что когда вы взаимодействуете с фреймворками и небольшими библиотеками, код хорошей практики, с которым вы будете взаимодействовать, будет чаще встречаться в более крупных фреймворках.
Это заблуждение очень часто, например , каждый врач я лечились был высокомерен. Поэтому я делаю вывод, что все врачи высокомерны. Эти ошибки всегда страдают от общего вывода, основанного на личном опыте.
В вашем случае возможно, что вы в основном испытали хорошую практику в больших средах, а не в меньших библиотеках. Ваше личное наблюдение не является ошибочным, но это неподтвержденное свидетельство и не всегда применимо.
Вы несколько подтверждаете это здесь. Подумайте, что такое основа. Это не приложение. Это обобщенный «шаблон», который другие могут использовать для создания всевозможных приложений. По логике это означает, что фреймворк построен в гораздо более абстрактной логике, чтобы его могли использовать все.
Разработчики фреймворков не могут использовать ярлыки, потому что они даже не знают, каковы требования последующих приложений. Создание фреймворка по своей сути стимулирует их сделать свой код пригодным для использования другими.
Однако разработчики приложений могут пойти на компромисс в отношении логической эффективности, поскольку они сосредоточены на предоставлении продукта. Их главная цель - не работа кода, а опыт пользователя.
Для фреймворка конечный пользователь - это другой разработчик, который будет взаимодействовать с вашим кодом. Качество вашего кода важно для вашего конечного пользователя.
Для приложения конечный пользователь не является разработчиком и не будет взаимодействовать с вашим кодом. Качество вашего кода не имеет для них значения.
Именно поэтому архитекторы команды разработчиков часто выступают в качестве навязчиков передовой практики. Они находятся в одном шаге от доставки продукта, что означает, что они склонны смотреть на код объективно, а не фокусироваться на доставке самого приложения.
Это интересный момент, и это (по моему опыту) главная причина, почему люди все еще пытаются оправдать отказ от хорошей практики.
Подводя итог следующим пунктам: Пропуск надлежащей практики может быть оправдан только в том случае, если ваши требования (как известно в настоящее время) являются неизменными, и никогда не будет каких-либо изменений / дополнений в кодовой базе. Оповещение спойлера: это редко случается.
Например, когда я пишу 5-минутное консольное приложение для обработки определенного файла, я не пользуюсь хорошей практикой. Потому что я собираюсь использовать приложение только сегодня, и его не нужно обновлять в будущем (было бы проще написать другое приложение, если оно мне понадобится снова).
Допустим, вы можете создать приложение за 4 недели, а за 6 недель - правильно. С первого взгляда, к сожалению, здание кажется лучше. Заказчик получает свое приложение быстрее, и компании приходится тратить меньше времени на заработную плату разработчика. Победа / победа, верно?
Однако это решение принято, не задумываясь. Из-за качества кодовой базы внесение основных изменений в плохо построенную версию займет 2 недели, в то время как внесение таких же изменений в правильно построенную версию займет 1 неделю. В будущем может произойти много таких изменений.
Более того, существует тенденция к неожиданным изменениям, требующим больше работы, чем вы изначально думали, в плохо построенных кодовых базах, что, вероятно, сокращает время разработки до трех недель вместо двух.
А также есть тенденция тратить время на охоту за ошибками. Это часто имеет место в проектах, где ведение журнала было проигнорировано из-за нехватки времени или явного нежелания его реализовать, потому что вы рассеянно работаете в предположении, что конечный продукт будет работать так, как ожидалось.
Это даже не должно быть серьезным обновлением. У моего нынешнего работодателя я видел несколько проектов, которые были построены быстро и грязно, и когда нужно было сделать крошечную ошибку / изменение из-за неправильного представления требований, что привело к цепной реакции необходимости рефакторинга модуля за модулем , Некоторые из этих проектов рухнули (и оставили после себя неразбериху), прежде чем они выпустили свою первую версию.
Быстрые решения (быстрое и грязное программирование) полезны только в том случае, если вы можете окончательно гарантировать, что требования в точности верны и их не нужно менять. По моему опыту, я никогда не сталкивался с проектом, где это правда.
Вложение дополнительного времени в хорошую практику - это инвестирование в будущее. Будущие ошибки и изменения будут намного проще, если существующая кодовая база будет построена на основе хорошей практики. Он будет выплачивать дивиденды только после двух или трех изменений.
источник
Как SOLID превращает простой код в код фреймворка? Я не стану любителем SOLID, но на самом деле не совсем понятно, что вы имеете в виду.
Я признаю, что я не думаю, что в терминах SOLID сам, потому что я прошел через школу программирования Gang of Four и Josh Bloch , а не школу Bob Martin. Но я действительно думаю, что если вы думаете «SOLID» = «добавление большего количества слоев в технологический стек», вы читаете это неправильно.
PS Не продавайте преимущества «лучшего UX для разработчика». Код проводит большую часть своей жизни в обслуживании. Разработчик - это ты .
источник
class A{ int X; int Y; } class A_setX{ f(A a, int N) { a.X = N; }} class A_getX{ int f(A a) { return X; }} class A_setY ... etc.
я думаю, что вы смотрите на это слишком мета с точки зрения вашей фабричной претензии. Инициализация не является аспектом проблемы домена.