2010-06-08 5 views
36

Шаблон дизайна, обозначенный первой буквой в этом аббревиатуре, является принципом единой ответственности. Вот цитата:Являются ли СОВРЕМЕННЫЕ принципы действительно прочными?

единый принцип ответственности гласит, что каждый объект должен быть единую ответственность, и что ответственность должна быть полностью инкапсулированный классом.

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

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

Так что мой вопрос. Можно ли строго придерживаться SRP? Как это можно сделать?

+0

Сообщество Wiki? –

+5

@C. Росс: Я думаю, что это достаточно конкретный факт, что он не принадлежит к записи в Community Wiki. –

+0

Если вы определяете ответственность класса как «делать то, что он кодирует», то SRP является самореализующимся. Так что это действительно зависит от того, как вы определяете «ответственность». «Реализуйте характеристики X, включая сериализацию, сравнение, ...» Я думаю, что это была бы единственная ответственность. Единая ответственность =/= единая функциональность. –

ответ

64

Как вы когда-нибудь обнаружите, ни один из самых известных принципов в разработке программного обеспечения не может быть на 100%.

Программирование часто связано с достижением компромиссов - абстрактной чистоты и размерами кода против скорости vs.efficiency.

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

+8

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

+0

SOLID, возможно, нуждается в другой букве в аббревиатуре: P для «Pick your battles», чтобы подчеркнуть тот факт, что проекты - это компромиссы. В этой статье есть несколько хороших анекдотов: http://www.martinfowler.com/ieeeSoftware/protectedVariation.pdf – Fuhrmanator

12

Я не думаю, что быть сериализуемым или одноразовым составляет несколько обязанностей.

+8

Согласовано. И SRP является наиболее «твердым» принципов SOLID, IMO. Другие могут иногда изгибаться, но SRP никогда не следует нарушать. –

+1

@ Stephen: Я думаю, что трюк здесь состоит в том, чтобы понять, что составляет единую ответственность. На практике это будет варьироваться в зависимости от того, что ожидается от класса, а также того, что требуется для того, чтобы «играть хорошо». –

+8

+1 - добавление атрибута не добавляет ответственности – STW

10

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

Я думаю, что заданный вами вопрос поднимает ключевой момент - как вы определяете единственную совместимость, которую должен иметь класс?

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

Однако, имейте это в виду. Хотя это, вероятно, невозможно применить во всех случаях - это все равно лучше, чем иметь в вашем коде один «объект Бога» (Anti-Pattern).

Если у вас возникли проблемы с этим я рекомендую прочитать следующее:

  • Рефакторинг - Мартин Фаулер: Несмотря на то, что, очевидно, о рефакторинга, эта книга также очень полезна при отображении, как разложить проблемы в их логические части или возможности, которые являются ключевыми для SRP. Эта книга также затрагивает другие принципы - однако она делает это гораздо менее академично, чем вы могли видеть раньше.

  • Чистый код - Роберт Мартин: Кто лучше читать, чем самый высокий показатель принципов SOLID. Серьезно, я нашел, что это действительно полезная книга во всех областях мастерства в области программного обеспечения - не только принципы SOLID.Как и книга Фаулера, эта книга разбита на всех уровнях опыта, поэтому я бы порекомендовал кого угодно.

+5

«Чистый код» - это книга, которую я читал, когда я, наконец, получил легкую попку OO/Testable-code на моем глава. Лучшая часть книги - это то, где очищается код с образцом до/после.То, что действительно поразило меня, было визуально, насколько наш код * выглядел так же, как раньше, это действительно помогло мне понять, в каком направлении двигаться код ради здравомыслия – STW

2

Что следует помнить о принципах дизайна, всегда есть исключения, и вы не всегда найдете, что ваш сценарий/реализация соответствует заданному принципу 100%.

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

2

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

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

5

Чтобы лучше понять SOLID принципы, которые вы должны понять проблему, которую они решают:

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

Итак ... SOLID появился как что-то вроде лакмусовой бумаги, чтобы ответить на вопрос «Я действительно занимаюсь ОО, или я просто использую процедурные объекты?» 5 принципов, если следовать, означает, что вы довольно далеко от OO-стороны спектра. Несоблюдение этих правил не означает, что вы не делаете OO, но это означает его гораздо более структурное/процедурное OO.

+3

Или, другими словами, вы не можете воспользоваться ОО , Это плохо, а не нейтрально. –

0

Изменяя свое определение «единоличная ответственность», принципы SOLID являются довольно ликвидными и (как и другие броские акронимы аббревиатур) не означают, что они означают.

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

+0

«СОВЕРШЕННЫЕ принципы довольно жидкие» Мне это нравится)) – Arseny

5

Здесь вызывает озабоченность, поскольку эти сквозные проблемы (сериализация, ведение журнала, уведомление о привязке данных и т. Д.) В конечном итоге добавляют реализацию к нескольким классам, которые существуют только для поддержки какой-либо другой подсистемы. Эта реализация должна быть проверена, поэтому класс определенно был обременен дополнительными обязанностями.

Аспектно-ориентированное программирование - это один из подходов, который пытается решить эту проблему. Хорошим примером в C# является сериализация, для которой существует множество различных атрибутов для разных типов сериализации. Идея здесь заключается в том, что класс не должен реализовывать код, который выполняет сериализацию, а скорее объявляет, как он должен быть сериализован. Метаданные - это очень естественное место, чтобы включать в себя детали, важные для других подсистем, но не относящиеся к проверяемой реализации класса.

+0

Это интересно. Я могу сказать другой подход. Помните, что я прочитал книгу о DDD (Domain Driven Design), где автор предлагает не писать atttibutes, а переносить ответственность за сериализацию в другой класс. Они называют это хранилище. – Arseny

+0

@ Арсений: Это интересно, но я не вижу, как это будет хорошо работать в среде .NET. –

-1

S.O.L.I.D обозначает:

  • Single ответственность Принцип
  • Open-замкнутый Принцип
  • Лиск в подмене Принцип
  • Интерфейс сегрегация Принцип
  • Принцип инверсии зависимостей

Эти стандарты мы говорим, когда говорим об ООП. Однако ни один из этих принципов не может быть отлично выполнен в разработке программного обеспечения.

Вы можете просмотреть очень хорошо объясняющую представление об этой теме здесь http://www.slideshare.net/jonkruger/advanced-objectorientedsolid-principles

1

Так что, если вместо того, чтобы проектировать один класс «собака» с «Барк», «Сон» и «Ешь» методы, я должен разработать " AnimalWhoBarks "," AnimalWhoSleeps "," AnimalWhoEats "и т. Д.? Зачем? Как это делает мой код лучше? Как я должен просто реализовать тот факт, что моя собака не заснет и будет лаять всю ночь, если он не ел?

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

Представьте, что платформа .NET была написана с использованием SRP. Вместо 40000 классов у вас будут миллионы.

Обобщенный SRP («Обобщенный» является важным словом здесь) является просто преступлением ИМХО. Вы не можете сократить разработку программного обеспечения до 5 принципов бухгалтерского учета.

+0

Большая проблема с обсуждениями, которые я видел в SRP, заключается в том, что они не могут отличить публичное лицо от типа и его реализации. Если код должен моделировать объект реального мира, который обладает многими способностями, он должен создать экземпляр класса, который предоставляет публичным членам доступ к этим возможностям. Если количество способностей велико, может быть желательно, чтобы класс, который раскрывает эти способности, служит главным образом в качестве обертки для частных объектов и связывает внешних публичных членов с объектами инкапсулированных объектов. – supercat

+0

Если 'MonitorableHeart' и' InjectableBloodStream' являются отдельными классами, код типа 'while (heart.rate()> 0 && heart.rate() <70) bloodstream.inject (drugs.someStimulant);' будет вести себя очень плохо, если дано «MonitorableHeart», связанный с одной собакой, и «InjectableBloodStream», связанный с другим. Однако, если методы «запрос-сердечный ритм» и «инъекционный наркотик» относятся к одному и тому же объекту «Собака», эта проблема исчезает. – supercat

+0

Однако, если в будущем вы создадите еще несколько существ, которые могут «спать», «съесть» или, может быть, «Bark». Вероятно, у вас будет много дублированного кода. Лучше сконструировать Собака как составную часть его функций, потому что если вам нужен другой тип животного, вы можете создать другой композит. Что касается комментариев @ supercat, я действительно не понимаю. – RockyMM

Смежные вопросы