членовите

Отворено / затворено, според принципот СОЛИД

Софтверските субјекти (класи, модули, функции, итн.) Треба да бидат отворени за проширување, но затворени за уредување.

Дизајн на софтвер: модули, класи и функции на таков начин што кога е потребна нова функционалност, не треба да го менуваме постојниот код, туку да напишеме нов код што ќе го користи постојниот код. Ова може да звучи чудно, особено со јазици како Java, C, C ++ или C # каде што се однесува не само на самиот изворен код, туку и на бинарниот. Ние сакаме да создадеме нови одлики на начини што не бараат прераспределба на постојните бинарни, извршни или DLL.
OCP во СОЛИДЕН контекст

 

SRP и OCP комплементарни

Ние веќе го видовме принципот СРП за единствена одговорност, кој вели дека модулот треба да има само една причина да се менува. Принципите на ОЦП и СРП се комплементарни. Кодот дизајниран следејќи го принципот SRP исто така ќе ги почитува принципите на OCP. Кога имаме код што има само една причина да се промени, воведувањето нова опција ќе создаде второстепена причина за таа промена. Така и СРП и ОЦП ќе бидат прекршени. Исто така, ако имаме код кој треба да се менува само кога неговата главна функција се менува и треба да остане непроменет кога ќе се додаде нова функционалност, со тоа почитувајќи го OCP, тој најмногу ќе го почитува и SRP.
Ова не значи дека SRP секогаш доведува до OCP или обратно, но во повеќето случаи ако се почитува еден од нив, постигнувањето на второто е прилично едноставно.

 

Пример за кршење на принципот на OCP

Од чисто техничка гледна точка, принципот Отворено / затворено е многу едноставен. Едноставна врска помеѓу две класи, како онаа подолу, го нарушува принципот OCP.

Корисничката класа директно ја користи класата Logic. Ако треба да имплементираме втора класа Logic на начин што ќе ни овозможи да ги користиме и тековната и новата, постојната класа Logic ќе треба да се смени. Корисникот е директно врзан за имплементација на логиката, не постои начин да обезбедиме нова логика без да влијаеме на сегашната. И кога зборуваме за статички внесени јазици, многу е веројатно дека Корисничката класа ќе бара и модификации. Ако зборуваме за компајлирани јазици, сигурно дека и Извршливиот корисник и Извршната логика или динамичката библиотека ќе бараат повторна компилација и испорака, по можност да се избегнат кога е можно.

Повикувајќи се на претходната шема, можеме да заклучиме дека секоја класа што директно користи друга класа, може да доведе до кршење на принципот Отворено / затворено. 
Да претпоставиме дека сакаме да напишеме класа што може да обезбеди напредок "во проценти" на преземената датотека, преку нашата апликација. Haveе имаме две главни класи, Напредок и Датотека, и претпоставувам дека би сакале да ги користиме на следниов начин:

 

тест на функцијатаItCanGetTheProgressOfAFileAsAPercent () {
     $ датотека = нова датотека ();
     $ датотека-> должина = 200;
     $ датотека-> испратена = 100;
     $ напредок = нов напредок (датотека $);
     $ this-> assertEquals (50, $ progress-> getAsPercent ());
}

Во овој код ние сме корисници на Прогрес. Ние сакаме да добиеме вредност како процент, без оглед на реалната големина на датотеката. Ние ја користиме Датотеката како извор на информации. Датотеката има должина во бајти и поле наречено испратено што претставува количина на податоци испратени до симнувачот. Не ни е гајле како овие вредности се ажурираат во апликацијата. Можеме да претпоставиме дека постои некоја волшебна логика што го прави ова за нас, така што на тест можеме експлицитно да ги поставиме.

 

класа Датотека {
     јавна должина $;
     јавно испратено $;
}

 

Класата File е само едноставен податочен објект што ги содржи двете полиња. Секако дека треба да содржи и други информации и однесувања, како што се име на датотека, патека, релативна патека, тековен директориум, тип, дозволи и сл.

 

класа Напредок {

     приватна датотека $;

     функција __construction (Датотека $ датотека) {
          $ ова-> датотека = $ датотека;
     }

     функција getAsPercent () {
          вратете $ ова-> датотека-> испратено * 100 / $ ова-> датотека-> должина;
     }

}

Прогресот е едноставно класа што прифаќа датотека во нејзиниот конструктор. За јасност, ние го наведовме типот на променлива во параметрите на конструкторот. Постои единствен корисен метод за Progress, getAsPercent (), кој ќе ги земе испратените вредности и должина од File и ќе ги претвори во процент. Едноставно и работи.

Овој код се чини дека е точен, сепак го крши принципот Отворено / затворено.

Но зошто?

И како?

 

Ајде да се обидеме да ги смениме барањата

Секоја апликација ќе има потреба од нови карактеристики за да се развива со текот на времето. Нова опција за нашата апликација може да биде да дозволиме стриминг на музика наместо само преземање датотеки. Должината на датотеката е претставена во бајти, времетраењето на музиката во секунди. Ние сакаме да им понудиме лента за напредок на нашите слушатели, но дали можеме повторно да го користиме часот напишан погоре?

Не не можеме. Нашата прогресија е обврзана датотека. Може да управува само со информации за датотеки, иако може да се примени и на музичка содржина. Но, за да го сториме тоа, мора да го модифицираме, мораме да го натераме Напредокот да ја знае музиката и датотеките. Ако нашиот дизајн беше во согласност со OCP, не треба да допираме Датотека или Прогрес. Можевме само да го искористиме постојниот напредок и да го примениме на музиката.

 

Билтен за иновации
Не пропуштајте ги најважните вести за иновациите. Пријавете се за да ги добивате по е-пошта.

Можно решение

Динамички внесените јазици имаат предност во управувањето со типовите на предмети при извршувањето. Ова ни овозможува да го отстраниме пишувањето од конструкторот Progress и кодот ќе продолжи да работи.

класа Напредок {

     приватна датотека $;

     функција __construction ($ датотека) {
         $ ова-> датотека = $ датотека;
     }

    функција getAsPercent () {
         вратете $ ова-> датотека-> испратено * 100 / $ ова-> датотека-> должина;
     }

}

Сега можеме да лансираме сè на Прогрес. И под ништо, мислам буквално на што било:

класа Музика {

јавна должина $;
јавно испратено $;

јавен $ уметник;
јавен албум $;
јавно $ releaseDate;

функција getAlbumCoverFile () {
вратете ги 'Слики / обвивки /'. $ ова-> уметник. '/'. $ ова-> албум. '.png';
}
}

И часот по Музика како горенаведениот ќе работи совршено. Лесно можеме да го тестираме со тест многу сличен на File.
тест на функцијатаItCanGetTheProgressOfAMusicStreamAsAPercent () {
$ музика = нова музика ();
$ музика-> должина = 200;
$ музика-> испратена = 100;

$ напредок = нов напредок ($ музика);

$ this-> assertEquals (50, $ progress-> getAsPercent ());
}

Значи, во основа секоја мерлива содржина може да се користи со класата Progress. Можеби треба да го ставиме во код со промена на името на променливата исто така:

класа Напредок {

приватна $ мерлива содржина;

функција __конструирај ($ мерлива содржина) {
$ ова-> мерлива содржина = $ мерлива содржина;
}

функција getAsPercent () {
вратете $ ова-> мерлива содржина-> испратена * 100 / $ оваа-> мерлива содржина-> должина;
}

}

Кога ја наведовме File како типка, бевме оптимисти за тоа што може да се справи со нашата класа. Тоа беше експлицитно и ако дојдеше нешто друго, голема грешка ќе ни кажеше.

Una класа што надминува метод на основна класа, така што договорот за основна класа не е почитуван од изведената класа. 

Ние не сакаме да се обидеме да повикаме методи или полиња за пристап на објекти кои не се во согласност со нашиот договор. Кога имавме пишување, договорот беше прецизиран од него. Полињата и методите од класата File. Сега, кога немаме ништо, можеме да испратиме што било, дури и низа и тоа ќе резултира со лоша грешка.

Додека крајниот резултат е ист во двата случаи, што значи дека кодот се распаѓа, првиот произведе убава порака. Ова, сепак, е многу темно. Не постои начин да се знае што е променливата - низа во нашиот случај - и кои својства се барани и не се пронајдени. Тешко е да се дебагира и да се поправи проблемот. Програмерот мора да ја отвори класата Progress, да ја прочита и разбере. Договорот, во овој случај, кога не го специфицирате експлицитно написот, е defiуништени од однесувањето на Прогресот. Тоа е имплицитен договор познат само на Прогрес. Во нашиот пример, тоа е defiсе завршува со пристап до двете полиња, испратени и должина, во методот getAsPercent(). Во реалниот живот имплицитниот договор може да биде многу сложен и тешко да се открие со само гледање неколку секунди на час.

Ова решение се препорачува само ако никој од другите совети подолу не може лесно да се спроведе или ако тие нанесат сериозни архитектонски промени што не го гарантираат трудот.

Ercole Palmeri

Билтен за иновации
Не пропуштајте ги најважните вести за иновациите. Пријавете се за да ги добивате по е-пошта.

Последни написи

Новата вештачка интелигенција на Google може да моделира ДНК, РНК и „сите молекули на животот“

Google DeepMind воведува подобрена верзија на својот модел за вештачка интелигенција. Новиот подобрен модел обезбедува не само…

9 мај 2024

Истражување на модуларната архитектура на Ларавел

Ларавел, познат по својата елегантна синтакса и моќните карактеристики, исто така обезбедува цврста основа за модуларна архитектура. Таму…

9 мај 2024

Cisco Hypershield и стекнување на Splunk Започнува новата ера на безбедност

Cisco и Splunk им помагаат на клиентите да го забрзаат своето патување до Центарот за безбедносни операции (SOC) на иднината со…

8 мај 2024

Надвор од економската страна: неочигледната цена на откупниот софтвер

Ransomware доминира во вестите во последните две години. Повеќето луѓе се свесни дека нападите…

6 мај 2024

Иновативна интервенција во зголемена реалност, со гледач на Apple во поликлиниката Катанија

Операција на офталмопластика со помош на комерцијалниот прегледувач на Apple Vision Pro беше извршена во поликлиниката Катанија…

3 мај 2024

Придобивките од боење страници за деца - свет на магија за сите возрасти

Развивањето на фини моторни вештини преку боење ги подготвува децата за посложени вештини како пишување. Да обои…

2 мај 2024

Иднината е тука: Како бродската индустрија ја револуционизира глобалната економија

Поморскиот сектор е вистинска глобална економска сила, која навигираше кон пазар од 150 милијарди ...

1 мај 2024

Издавачите и OpenAI потпишуваат договори за регулирање на протокот на информации обработени од вештачката интелигенција

Минатиот понеделник, Financial Times објави договор со OpenAI. ФТ го лиценцира своето новинарство од светска класа…

Април 30 2024

Читајте иновации на вашиот јазик

Билтен за иновации
Не пропуштајте ги најважните вести за иновациите. Пријавете се за да ги добивате по е-пошта.

Следете нас