Является Открываться/Закрывать Principle хорошей идеей? [закрытый]

Попытайтесь добавить пару атрибутов класса, скажите 'даже' и 'нечетный' к переменным элементам списка, например,

<ul>
    <li class="even"><a href="link">Link 1</a></li>
    <li class="odd"><a href="link">Link 2</a></li>
    <li class="even"><a href="link">Link 3</a></li>
    <li class="odd"><a href="link">Link 4</a></li>
    <li class="even"><a href="link">Link 5</a></li>
</ul>

В < style> раздел страницы HTML, или в связанной таблице стилей, Вы определили бы те те же классы, указав Ваши желаемые цвета фона:

li.even { background-color: red; }
li.odd { background-color: blue; }

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

11
задан Rogério 12 September 2009 в 23:44
поделиться

6 ответов

OCP имеет большой смысл, когда вы не являетесь потребителем своего кода. Если я пишу класс, и я или моя команда пишем все классы, которые его используют, я соглашусь. Рефакторинг по мере того, как вещи меняются, совсем не представляет большого труда.

Если, с другой стороны, я пишу API для своих клиентов, или у меня есть несколько потребителей в большой организации с разными интересами, OCP имеет решающее значение, потому что я могу Не так легко провести рефакторинг.

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

8
ответ дан 3 December 2019 в 07:38
поделиться

Я никогда не слышал о OCP. Возможно, вы имеете в виду что-то еще, но известный мне OCP говорит: «Модуль / класс должен быть открыт для расширения , но закрыт для модификации , что означает, что вы не должны изменять исходный код модуля для его улучшения, но модуль или объект должны легко расширяться.

Подумайте о eclipse (или о любом другом программном обеспечении на основе плагинов, если на то пошло). У вас нет исходного кода, но любой может напишите плагин, чтобы расширить поведение или добавить другую функцию. Вы не изменяли eclipse, но вы расширили его.

Итак, да, принцип Open / Closed действительно очень верен и неплохая идея.

ОБНОВЛЕНИЕ:

Я вижу, что основной конфликт здесь возникает между кодом, который все еще находится в стадии разработки, и кодом, который уже отправлен и кем-то уже используется. Итак, я пошел и посоветовался с Бертраном Мейером , автором этого принципа. Он говорит:

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

Итак, действительно, принцип открытости / закрытости относится только к стабильным, готовым к компиляции и использованию объектам.

4
ответ дан 3 December 2019 в 07:38
поделиться

Хорошо, вот мой ответ.

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

Предположим, у нас есть компонент.

public class KnownFriendsFilter{
  IList<People> _friends;
  public KnownFriendsFilter(IList<People> friends) {
    _friends = friends;
  }
  public IList<Person> GetFriends(IList<Person> people) {
    return people.Where(p=>_friends.Contains(p)).ToList();
  }
}

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

Однако есть разница между этим классом и функцией, которую он поддерживает.

  • Этот класс на самом деле предназначен только для фильтрации массива людей по известным друзьям.
  • Функция, которую он поддерживает, - это поиск всех друзей из массива людей.

Разница в том, что эта функция связана с функцией, в то время как класс занимается реализацией. Большинство запросов, которые мы получаем для изменения этой функции, выходят за рамки конкретной ответственности класса.

Например, допустим, мы хотим добавить в черный список любые имена, начинающиеся с буквы «X» (потому что эти люди, очевидно, являются космонавтами, а не нашими друзьями). Это то, что поддерживает функцию, но на самом деле не является частью того, о чем весь этот класс, вставлять его в класс было бы неудобно. Как насчет того, когда придет следующий запрос, когда приложение используется исключительно женоненавистниками, и любые женские имена также должны быть исключены? Теперь вам нужно добавить логику, чтобы решить, мужское или женское имя в классе - или, по крайней мере, знать о каком-то другом классе, который знает, как это сделать - класс растет в сфере ответственности и становится очень раздутым! А как насчет сквозных проблем? Теперь мы хотим регистрировать каждый раз, когда мы фильтруем массив людей, это тоже идет прямо туда?

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

2
ответ дан 3 December 2019 в 07:38
поделиться

Интересный вопрос, и, основываясь на строгом определении принципа «открыто-закрыто», я могу понять, откуда вы пришли.

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

Мне нравится говорить, что все мои классы (в целом), участвующие в приложении, должны быть закрыты для модификации и открыты для расширения. Итак, принцип заключается в том, что если мне нужно изменить поведение и / или работу приложения, я фактически не изменяю класс, а добавляю новый, а затем меняю отношения, чтобы указать на этот новый (в зависимости, конечно, от размера изменения). Если я следую единственной ответственности и использую инверсию контроля, это должно произойти. Затем происходит то, что все изменения становятся расширениями.

1
ответ дан 3 December 2019 в 07:38
поделиться

Итак, действительно ли OCP имеет смысл сегодня? Я так не думаю.

Иногда так бывает:

  • Когда вы выпустили базовый класс для клиентов и не можете легко изменить его на всех машинах ваших клиентов (см., Например, «Ад DLL»)

  • Когда вы заказчик, который сам не писал базовый класс и не поддерживает его

  • В общем, любая ситуация, когда базовый класс используется более чем одной командой и / или более чем проект

См. также Закон Конвея .

1
ответ дан 3 December 2019 в 07:38
поделиться

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

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

Вы можете представить себе зависящие от языка инструменты слияния / ветвления, которые могут выполнять три параллельных рефакторинга и объединять их так же легко, как изменения в изолированных файлах. Но таких инструментов не существует, и если бы они были, я бы не стал на них полагаться.

0
ответ дан 3 December 2019 в 07:38
поделиться
Другие вопросы по тегам:

Похожие вопросы: