Last updated
Last updated
Както подсказва името, този принцип гласи, че софтуерните обекти трябва да бъдат отворени за разширение, но затворени за модификация. В резултат на това, когато бизнес изискванията се променят (условието на задачата се надгради) тогава обектът може да бъде разширен, но не и модифициран.
Нека да разгледаме следния пример:
Започваме с класическа итара, но след някоплко месеца решаваме, че една китара брандирана с пламаци ще изглежда по-рокендрол
В този момент може да е съблазнително просто да отворим класа "Китара" и да добавим поле за пламъка — но кой знае какви грешки може да доведе това в нашия клас.
Вместо това нека се придържаме към принципа на отворените за разширение класове и просто да разширим класа си Китара:
Разширявайки класа Китара, сме сигурни, досегашното ни приложениое няма да бъде засегнато, а това за което трябва да мислим е само новата функционалност.
Ще разгледаме как интерфейсите са един от начините да следвате на този принцип
Нека разгледаме изграждането на приложение за калкулатор, което може да има няколко операции, като например добавяне и изваждане.
На първо място, ще определим интерфейс от най-високо ниво – CalculatorOperation:
Нека създадем клас "Добавяне", който би събрал две числа и би разшерил CalculatorOperation:
От сега имаме само един клас Добавяне, така че трябва да определим друг клас на име Изваждане:
Нека сега определим нашия основен клас, който ще изпълни нашите калкулаторни операции:
Въпреки че това може да изглежда добре, това не е добър пример за OCP. Когато влезе ново изискване за добавяне на умножение или функционалност за разделяне, нямаме начин освен да променим метода на изчисляване на клас Калкулатор.
Оттук можем да кажем, че този код не е съвместим с OCP.
Както видяхме нашето приложение за калкулатор все още не е съвместимо с OCP. Кодът в метода на изчисляване ще се промени с всяко входящо ново искане за поддръжка на операция. Така че, трябва да извлечем този код и да го сложим в абстракционен слой.
Едно решение е всяка операция да бъде делегирана в съответния им клас:
В резултат на това класът "Добавяне" би могъл да внедри логиката на добавяне на два номера:
По същия начин актуализиран клас на Изваждане би имал подобна логика. И подобно на Добавяне и Изваждане, като настъпи нова задача за промяна, бихме могли да внедрим логиката на разделението:
И накрая, нашият клас Калкулатор няма нужда да прилага нова логика, когато въвеждаме нови оператори:
Така класът е затворен за модификация, но отворен за разширение.
Принципа на отворени за разширение и затворени за модификация обекти, подобрава работата върху проектите, като намалява грешките, който могат да възникнат при модифициране на класове и улеснява тестването като капсолира вече съществуващата логика и предоставя възможност за концентрация върху новата логика на приложениет.