В чем смысл и обоснование открытого / закрытого принципа? - PullRequest
39 голосов
/ 12 сентября 2008

Принцип Open / Closed гласит, что программные объекты (классы, модули и т. Д.) Должны быть открыты для расширения, но закрыты для модификации. Что это значит и почему это важный принцип хорошего объектно-ориентированного проектирования?

Ответы [ 11 ]

39 голосов
/ 12 сентября 2008

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

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

23 голосов
/ 12 сентября 2008

В частности, речь идет о «Святом Граале» проектирования в ООП, заключающегося в том, чтобы сделать объект достаточно расширяемым (посредством его индивидуального дизайна или посредством участия в архитектуре) для поддержки будущих непредвиденных изменений без переписывания кода (а иногда даже без перекомпиляция **).

Некоторые способы сделать это включают Полиморфизм / Наследование, Композицию, Инверсию Управления (также известный как DIP), Аспектно-ориентированное программирование, Шаблоны, такие как Стратегия, Посетитель, Шаблонный метод, и многие другие принципы, шаблоны и методы OOAD.

** См. 6 «принципов пакета», REP, CCP, CRP, ADP, SDP, SAP

5 голосов
/ 04 июля 2017

Программные объекты должны быть открыты для расширения, но закрыты для модификации

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

Плохой пример в Javascript

var juiceTypes = ['Mango','Apple','Lemon'];
function juiceMaker(type){
    if(juiceTypes.indexOf(type)!=-1)
        console.log('Here is your juice, Have a nice day');
    else
        console.log('sorry, Error happned');
}

exports.makeJuice = juiceMaker;

Теперь, если вы хотите добавить еще один тип сока, вам нужно отредактировать сам модуль. Таким образом мы нарушаем OCP.

Хороший пример в Javascript

var juiceTypes = [];
function juiceMaker(type){
    if(juiceTypes.indexOf(type)!=-1)
        console.log('Here is your juice, Have a nice day');
    else
        console.log('sorry, Error happned');
}
function addType(typeName){
    if(juiceTypes.indexOf(typeName)==-1)
        juiceTypes.push(typeName);
}
function removeType(typeName){
  let index = juiceTypes.indexOf(typeName)
    if(index!==-1)
        juiceTypes.splice(index,1);
}

exports.makeJuice = juiceMaker;
exports.addType = addType;
exports.removeType = removeType;

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

5 голосов
/ 12 сентября 2008

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

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

5 голосов
/ 12 сентября 2008

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

2 голосов
/ 12 сентября 2008

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

Часто полиморфизм, например, с использованием интерфейсов, является хорошим инструментом для достижения этой цели.

1 голос
/ 08 декабря 2008

Я просто хочу подчеркнуть, что «Open / Closed», хотя он, очевидно, полезен в ОО-программировании, является здоровым методом для использования во всех аспектах разработки. Например, по моему собственному опыту, это отличный болеутоляющий, чтобы максимально использовать "Open / Closed" при работе с простым C.

/ Robert

1 голос
/ 17 ноября 2008

Дополнительное практическое правило для соответствия OCP состоит в том, чтобы сделать базовые классы абстрактными относительно функциональности, предоставляемой производными классами. Или, как говорит Скотт Мейерс: «Делайте не листовые классы абстрактными».

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

0 голосов
/ 23 декабря 2016

В принципе дизайна SOLID - «O» в «SOLID» обозначает принцип «открыт / закрыт».

Принцип Open Closed - это принцип разработки, который гласит, что класс, модули и функции должны быть открыты для расширения, но закрыты для модификации.

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

Преимущество открытого закрытого принципа проектирования:

  1. Приложение будет более устойчивым, потому что мы не меняем уже протестированный класс.
  2. Гибкость, потому что мы можем легко приспособить новые требования.
  3. Прост в тестировании и менее подвержен ошибкам.

Мой пост в блоге об этом:

http://javaexplorer03.blogspot.in/2016/12/open-closed-design-principle.html

0 голосов
/ 19 мая 2012

Мне недавно дали дополнительное представление о том, что влечет за собой этот принцип: что принцип Open-Closed сразу описывает способ написания кода, а также конечный результат написания кода гибким способом.

Мне нравится думать о разделении Open / Closed на две тесно связанные части:

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

Таким образом, код, демонстрирующий поведение Open / Closed (или, если вы предпочитаете, соответствует принципу Open / Closed), требует минимальной модификации или не требует изменений в ответ на сценарии использования, помимо того, для чего он был изначально создан.

Что касается реализации? Я нахожу, что общепринятая интерпретация «Открытый / Закрытый относится к полиморфному коду!» быть в лучшем случае неполным утверждением. Полиморфизм в коде является одним из инструментов для достижения такого рода поведения; Наследование, реализация ... действительно, каждый принцип объектно-ориентированного проектирования необходим для написания кода, который был бы устойчивым в соответствии с этим принципом.

...