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

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

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

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


person Thiru    schedule 28.01.2009    source источник
comment
Думаю, вам стоит превратить это в вики, поскольку нет однозначного ответа.   -  person    schedule 28.01.2009
comment
Я не уверен, что согласен. Я думаю, что это более и менее правильные ответы. И я думаю, что слишком многие люди считают, что это гораздо более субъективно или контекстно-зависимо, чем оно есть на самом деле - отчасти поэтому я разместил этот вопрос. Тем не менее, спасибо за ваш комментарий.   -  person Thiru    schedule 29.01.2009


Ответы (9)


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

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

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

person Mendelt    schedule 28.01.2009

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

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

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

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

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

person Community    schedule 28.01.2009

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

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

person BlackWasp    schedule 28.01.2009
comment
Я сомневаюсь, что кто-то из клиентов заботится о дисциплине разработчиков и соблюдении принципов объектно-ориентированного проектирования, но вы (или кто-либо другой), который должен поддерживать / работать с кодом, можете это оценить. - person Jim Anderson; 28.01.2009
comment
Я не согласен. Просто иногда прагматизм побеждает неукоснительное соблюдение именно этого принципа. - person BlackWasp; 29.01.2009

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

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

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

Понятия не имею, рассуждает ли Джоэл именно так, но я бы подошел к этой идее именно так.

person Welbog    schedule 28.01.2009

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

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

Павел.

person Paul W Homer    schedule 28.01.2009

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

person Jim Anderson    schedule 28.01.2009

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

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

Не уверен, что это касалось SRP, но идея та же. Принципы SOLID могут привести к противоречивым решениям, и этот барьер трудно преодолеть.

Для меня «руководящие принципы» более подходящее название, чем «принципы».

person Bogdan Kanivets    schedule 08.02.2009

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

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

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

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

person Chuck Conway    schedule 28.01.2009

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

GUI рядом с классами, как правило, отражает GUI и несет единственную ответственность «быть графическим интерфейсом для XXXX». Решение труса ..

person krosenvold    schedule 28.01.2009