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

Использование принципа единой ответственности в "реальном мире"

В основном я хочу получить представление о проценте людей, которые считают разумным использовать принцип единой ответственности в реальном коде и, сколько на самом деле. В Podcast # 38 Джоэл рассказывает о том, как бесполезно этот принцип ООП - это реальный мир; и далее, что это демонстрирует, как люди, подобные дяде Бобу, скорее всего, не писали нетривиальные системы.

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

Что думает сообщество?

4b9b3361

Ответ 1

У меня был некоторый опыт применения принципов SOLID, и мой опыт был в основном хорош. Я также слышал подкаст, и похоже, что ни Джефф, ни Джоэл не пробовали ни одной из вещей, о которых они говорят достаточно долго, чтобы действительно осмыслить преимущества. Главный аргумент против - это, как правило, "вы пишете больше кода". Если я посмотрю, что я делаю, я напишу 10, возможно, на 20% больше кода (как правило, определения интерфейсов), но поскольку все очень развязано, оно гораздо более удобно. У меня почти никогда не бывает ситуаций, когда изменения в одной части моего приложения ломают другие части. Таким образом, 20% -ный дополнительный код, который я должен поддерживать, оплачивает сам.

Джефф также не заметил смысла в качестве кода. Он не видит качества кода в качестве большой выгоды для клиента. И он прав, клиенту все равно. Клиент действительно заботится о том, чтобы новые функции были реализованы быстро и что там, где качество кода приходит. Я обнаружил, что инвестиции в поддержание качества кода как можно выше всегда вернулись в течение нескольких месяцев. Высокое качество = низкое техническое обслуживание.

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

Ответ 2

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

Сначала классы были большими и делали несколько вещей. Чтобы изменить эти поведения, вам пришлось расширить эти классы. Все методы были виртуальными и не меняли состояние объекта, поэтому было довольно легко сделать это.

Но по мере того, как система росла, стало ясно, что структура будет в конечном итоге иметь ряд монолитных объектов, каждая из которых имеет цепи наследования looooong. Это также привело к неожиданным зависимостям - абстрактному методу, берущему коллекцию класса X, чтобы создать объект Y, определенный в базовом классе, продиктовало, что EVERYBODY должен был сделать это таким образом, даже если это не имело смысла для половины дерева наследования. Это также привело к массовым классам, которые потребовали десятков единичных тестов, чтобы получить покрытие кода более чем на 80%, и сложность была такой, что вы не были уверены, правильно ли вы все охватили. Было очевидно, что этот дизайн может стать очень жестким и негибким.

Итак, мы переработали все по линиям SRP. У вас будет свой интерфейс, базовый класс и, возможно, один или несколько классов реализации. Каждый из них состоял из разных объектов, которые выполняли ключевые функции всего процесса. Если вы хотите изменить одну часть, вы не переопределили метод, вы бы создали другой объект, который расширил требуемый интерфейс/базовый класс и выполнил свою работу по-разному. SRP даже сбрасывался в аргументы и возвращал значения методов класса. Для тех частей системы, которые должны быть гибкими, а не передавать коллекции класса X, которые используются для создания объектов Y, был создан класс для инкапсуляции процесса создания объектов Y. Компоненты системы затем передают этих производителей, объединяют их с другими (ответственность производителей) и в конечном итоге используют их для производства Y. Это позволило создать различные типы производителей, и все это можно было бы рассматривать точно то же самое, хотя они и делали совершенно разные вещи. Этот шаг также резко сократил базу кода каждого класса и сделал их намного проще для тестирования.

Я бы сказал, что, как новый разработчик, ОЧЕНЬ ТРУДНО разбить все до этого уровня. Вам почти нужно написать большой шар грязи, понять, как это работает, а затем перепроектировать его как несколько разных компонентов, каждый из которых несет ответственность за часть целого.

Ответ 3

Я не читал или не слушал комментарии Джоэла, поэтому не могу комментировать их конкретно.

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

Ответ 4

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

Вот почему был задуман АОП. Используя его, вам не нужно ничего менять, кроме классов ведения журнала, для изменения ведения журнала.

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

Я понятия не имею, что такое рассуждение Джоэла, но как я подхожу к этой идее.

Ответ 5

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

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

Павел.

Ответ 6

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

Ответ 7

Я думаю, что SOLID-принципы иногда не соответствуют естественной/бизнес-логике, которую обычно применяют при проектировании классов. Роберт К. Мартин привел пример классов Rectange и Square (квадрат не должен быть потомком Rectangle).

http://www.hanselminutes.com/default.aspx?showID=163

Я не уверен, что это касается SRP, но идея такая же. СОВРЕМЕННЫЕ принципы могут привести к противоречивым решениям, и трудно преодолеть этот барьер.

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

Ответ 8

В целом я согласен с принципами SOLID, но вы также должны учитывать их. Если вы пишете "Доказательство концепции", тогда принципы SOLID менее применимы.

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

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

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

Ответ 9

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

GUI рядом с классами, как правило, отражают GUI и несут единую ответственность за "быть gui для XXXX". Трусливое решение..