Попытайтесь добавить пару атрибутов класса, скажите 'даже' и 'нечетный' к переменным элементам списка, например,
<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; }
Вы могли бы хотеть использовать библиотеку шаблонов, поскольку Ваши потребности развиваются, чтобы предоставить Вам большую гибкость и сократить ввод. Почему тип все те элементы списка вручную?
OCP имеет большой смысл, когда вы не являетесь потребителем своего кода. Если я пишу класс, и я или моя команда пишем все классы, которые его используют, я соглашусь. Рефакторинг по мере того, как вещи меняются, совсем не представляет большого труда.
Если, с другой стороны, я пишу API для своих клиентов, или у меня есть несколько потребителей в большой организации с разными интересами, OCP имеет решающее значение, потому что я могу Не так легко провести рефакторинг.
Кроме того, если вы просто реорганизуете свой класс для удовлетворения всех потребностей, в результате вы получите раздутый класс. Если вы спроектировали класс так, чтобы потребители могли расширять ваш класс, а не изменять его, у вас действительно не было бы этой проблемы.
Я никогда не слышал о OCP. Возможно, вы имеете в виду что-то еще, но известный мне OCP говорит: «Модуль / класс должен быть открыт для расширения , но закрыт для модификации , что означает, что вы не должны изменять исходный код модуля для его улучшения, но модуль или объект должны легко расширяться.
Подумайте о eclipse (или о любом другом программном обеспечении на основе плагинов, если на то пошло). У вас нет исходного кода, но любой может напишите плагин, чтобы расширить поведение или добавить другую функцию. Вы не изменяли eclipse, но вы расширили его.
Итак, да, принцип Open / Closed действительно очень верен и неплохая идея.
ОБНОВЛЕНИЕ:
Я вижу, что основной конфликт здесь возникает между кодом, который все еще находится в стадии разработки, и кодом, который уже отправлен и кем-то уже используется. Итак, я пошел и посоветовался с Бертраном Мейером , автором этого принципа. Он говорит:
Модуль считается закрытым, если он доступен для использования другими модулями. Это предполагает что модулю дано четко определенное, стабильное описание (его интерфейс в чувство сокрытия информации). На уровне реализации закрытие для модуля также подразумевает, что вы можете скомпилировать его, возможно, сохранить в библиотеке и сделать доступным для других (его клиентов) использовать .
Итак, действительно, принцип открытости / закрытости относится только к стабильным, готовым к компиляции и использованию объектам.
Хорошо, вот мой ответ.
Я не могу свидетельствовать об историческом происхождении этого принципа, но он все еще часто используется в наше время. Я не думаю, что это опасно изменять функционирующий код (хотя это, конечно, так). Дело в том, чтобы позволить вам разделять идеи.
Предположим, у нас есть компонент.
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. Таким образом, вы можете поместить каждую из этих обязанностей в отдельный класс, который поддерживает именно это.
Интересный вопрос, и, основываясь на строгом определении принципа «открыто-закрыто», я могу понять, откуда вы пришли.
Я пришел к определению принципа «открыт-закрыт» несколько иначе, и этот принцип, я думаю, должен применяться, а именно, применять его гораздо шире.
Мне нравится говорить, что все мои классы (в целом), участвующие в приложении, должны быть закрыты для модификации и открыты для расширения. Итак, принцип заключается в том, что если мне нужно изменить поведение и / или работу приложения, я фактически не изменяю класс, а добавляю новый, а затем меняю отношения, чтобы указать на этот новый (в зависимости, конечно, от размера изменения). Если я следую единственной ответственности и использую инверсию контроля, это должно произойти. Затем происходит то, что все изменения становятся расширениями.
Итак, действительно ли OCP имеет смысл сегодня? Я так не думаю.
Иногда так бывает:
Когда вы выпустили базовый класс для клиентов и не можете легко изменить его на всех машинах ваших клиентов (см., Например, «Ад DLL»)
Когда вы заказчик, который сам не писал базовый класс и не поддерживает его
В общем, любая ситуация, когда базовый класс используется более чем одной командой и / или более чем проект
См. также Закон Конвея .
Дело в том, что такие современные инструменты позволяют разработчику изменять буквально тысячи строк кода, безопасно, за несколько секунд.
Что нормально, если у вас есть разработчик. Если вы работаете в группах, конечно, с контролем версий, возможно, с ветвлением и слиянием, то возможность гарантировать, что изменения от разных людей, как правило, в конечном итоге сосредоточиваются в разных файлах, очень важна для возможности контролировать то, что происходит.
Вы можете представить себе зависящие от языка инструменты слияния / ветвления, которые могут выполнять три параллельных рефакторинга и объединять их так же легко, как изменения в изолированных файлах. Но таких инструментов не существует, и если бы они были, я бы не стал на них полагаться.