макалалар

SOLID принцибине ылайык, ачык / жабык

Программалык жабдыктар (класстар, модулдар, функциялар ж.б.) кеңейтүү үчүн ачык, бирок түзөтүү үчүн жабык болушу керек.

Программалык камсыздоону: модулдарды, класстарды жана функцияларды, эгерде жаңы функциялар талап кылынса, биз учурдагы кодду өзгөртпөстөн, бар код менен колдонула турган жаңы кодду жазышыбыз керек. Бул таң калыштуу угулушу мүмкүн, айрыкча Java, C, C ++ же C # сыяктуу тилдерде, бул баштапкы коддун өзүнө гана эмес, экиликке дагы тиешелүү. Учурдагы экилик файлдарды, аткарылуучу файлдарды же DLL файлдарын кайра бөлүштүрүүнү талап кылбаган жолдор менен жаңы мүмкүнчүлүктөрдү түзгүбүз келет.
SOLID контекстиндеги OCP

 

Кошумча SRP жана OCP

Модулдун өзгөрүшү үчүн бир гана себеп болушу керек деген Бирдиктүү Жоопкерчиликтин SRP принцибин буга чейин көргөнбүз. OCP жана SRP принциптери бири-бирин толуктап турат. SRP принцибине ылайык иштелип чыккан код, ошондой эле OCP принциптерин сактайт. Эгерде бизде бир гана өзгөртүүгө негиз бар код бар болсо, жаңы функцияны киргизүү ошол өзгөрүүнүн экинчи себебин жаратат. Ошентип, SRP жана OCP да бузулган болот. Ошо сыяктуу эле, эгерде бизде анын негизги функциясы өзгөргөндө гана өзгөрүлө турган жана жаңы функционалдык функциялар кошулганда өзгөрүүсүз кала турган код бар болсо, демек, ОКПны эске алганда, ал негизинен SRPди да сыйлайт.
Бул SRP ар дайым OCPге алып келет дегенди билдирбейт же тескерисинче, бирок көпчүлүк учурда алардын бири аткарылса, экинчисине жетишүү оңой.

 

OCP принцибинин бузулушунун мисалы

Таза техникалык көз караштан алганда, Ачык / Жабык Принцип өтө жөнөкөй. Эки класстын ортосундагы жөнөкөй мамиле, төмөндөгүдөй, OCP принцибин бузат.

Колдонуучу классы Логика классын түздөн-түз колдонот. Эгерде экинчи Логика классын учурдагы жана жаңысын колдонууга мүмкүндүк берүүчү жол менен ишке ашыруу керек болсо, анда бар Логика классын өзгөртүү керек. Колдонуучу түздөн-түз логиканын ишке ашырылышына байланыштуу, бизде жаңы логиканы учурдагы логикага таасир этпестен берүү мүмкүнчүлүгү жок. Статикалык терилген тилдер жөнүндө сөз кылганда, Колдонуучу классы дагы өзгөрүүлөрдү талап кылат. Эгерде биз компиляцияланган тилдер жөнүндө айта турган болсок, анда Колдонуучунун экөө тең аткарыла турган жана Логика дагы, же динамикалык китепкана дагы компиляциялоону жана жеткирүүнү талап кылат, мүмкүн болушунча качкыла.

Мурунку схемага шилтеме берүү менен, башка классты түздөн-түз колдонгон ар кандай класс Ачык / Жабык принцибинин бузулушуна алып келиши мүмкүн. 
Биздин тиркеме аркылуу жүктөлүп алынган файлдын пайыздык көрсөткүчүн камсыз кыла турган класс жазууну каалайбыз деп коёлу. Бизде эки негизги класс бар, Прогресс жана Файл, менимче, биз аларды төмөнкүчө колдонгубуз келет:

 

function testItCanGetTheProgressOfAFileAsAPercent () {
     $ file = new File ();
     $ file-> length = 200;
     $ file-> sent = 100;
     $ progress = new Progress ($ file);
     $ this-> assertEquals (50, $ progress-> getAsPercent ());
}

Бул коддо биз Прогресстин колдонуучуларыбыз. Файлдын чыныгы көлөмүнө карабастан, проценттик мааниге ээ болгубуз келет. Файлды маалымат булагы катары колдонобуз. Файлдын байттык узундугу жана жүктөөчүгө жөнөтүлгөн маалыматтардын көлөмүн чагылдырган "Жөнөтүлгөн" деп аталган талаасы бар. Бул баалуулуктар тиркемеде кандайча жаңыланып жаткандыгы биз үчүн маанилүү эмес. Муну биз үчүн жасаган кандайдыр бир сыйкырдуу логика бар деп ойлошубуз мүмкүн, андыктан бир тестте биз аларды ачыкка коё алабыз.

 

класс файлы {
     коомдук $ узундугу;
     коомдук $ жөнөтүлдү;
}

 

Файл классы - бул эки талааны камтыган жөнөкөй маалымат объектиси. Албетте, анда файлдын аталышы, жол, салыштырмалуу жол, учурдагы каталог, түр, уруксаттар ж.б.у.с. сыяктуу башка маалыматтар жана жүрүм-турумдар камтылышы керек.

 

класс прогресси {

     жеке $ файлы;

     function __construct (Файл $ файлы) {
          $ this-> file = $ file;
     }

     getAsPercent () функциясы {
          return $ this-> file-> sent * 100 / $ this-> file-> length;
     }

}

Прогресс - бул файлды өзүнүн конструкторунда кабыл алган класс. Айкындуулук үчүн конструктордун параметрлеринде өзгөрмө түрүн көрсөттүк. Progressде getAsPercent () деген бирден-бир пайдалуу ыкма бар, ал Fileден жөнөтүлгөн маанилерди жана узундукту алып, аларды пайызга айландырат. Жөнөкөй жана ал иштейт.

Бул код туура окшойт, бирок Ачуу / Жабык принцибин бузат.

Бирок эмне үчүн?

Анан кантип?

 

Талаптарды өзгөртүүгө аракет кылалы

Убакыттын өтүшү менен өнүгүп келе жаткан ар бир колдонмо жаңы функцияларды талап кылат. Биздин колдонмонун жаңы өзгөчөлүгү файлдарды жүктөөнүн ордуна музыка агымына уруксат берүү болушу мүмкүн. Файлдын узундугу байт менен, музыканын узактыгы секунда менен чагылдырылат. Биз угуучуларга прогресс тилкесин сунуш кылгыбыз келет, бирок жогоруда жазылган классты кайрадан колдонсок болобу?

Жок, биз кыла албайбыз. Биздин өнүгүүбүз Файл менен байланыштуу. Ал файлдык маалыматты гана башкара алат, бирок аны музыка мазмунуна да колдонсо болот. Бирок аны жасаш үчүн, Прогресстин музыкасын жана файлдарын билишибиз керек. Эгерде биздин дизайн OCPге туура келсе, анда File же Progressге тийбешибиз керек болчу. Болгон прогрессти колдонуп, аны музыкага колдонсок болмок.

 

Инновациялык бюллетень
Инновация боюнча эң маанилүү жаңылыктарды өткөрүп жибербеңиз. Аларды электрондук почта аркылуу алуу үчүн катталыңыз.

Мүмкүн болгон чечим

Динамикалык түрдө терилген тилдер объектилердин типтерин иштетүү убагында башкаруунун артыкчылыгына ээ. Бул бизге Прогресс конструкторунан тексттин изин алып салууга мүмкүндүк берет жана код иштей берет.

класс прогресси {

     жеке $ файлы;

     function __construct ($ file) {
         $ this-> file = $ file;
     }

    getAsPercent () функциясы {
         return $ this-> file-> sent * 100 / $ this-> file-> length;
     }

}

Эми биз Прогрессте каалаган нерсени ишке киргизсек болот. Кандай болсо дагы, мен түзмө-түз бир нерсени айткым келет:

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

коомдук $ узундугу;
коомдук $ жөнөтүлдү;

public $ artist;
коомдук $ альбому;
public $ releaseDate;

getAlbumCoverFile () функциясы {
return 'Images / Covers /'. $ this-> artist. '/'. $ this-> album. '.png';
}
}

Ал эми жогорудагыдай Музыка классы мыкты иштейт. Биз аны Файлга өтө окшош тест аркылуу оңой эле текшере алабыз.
function testItCanGetTheProgressOfAMusicStreamAsAPercent () {
$ музыка = жаңы Музыка ();
$ music-> length = 200;
$ music-> sent = 100;

$ progress = new Progress ($ music);

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

Ошентип, негизинен, каалаган ченелүүчү мазмунду Прогресс классы менен колдонсо болот. Балким, аны өзгөрмө аталышын өзгөртүп, аны код менен билдиришибиз керек:

класс прогресси {

жеке $ өлчөнүүчүContent;

function __construct ($ measureurableContent) {
$ this-> өлчөнүүчүContent = $ өлчөнүүчүContent;
}

getAsPercent () функциясы {
return $ this-> measureurableContent-> sent * 100 / $ this-> өлчөнүүчүContent-> узундук;
}

}

Файлды терип басуу иретинде көрсөткөндө, биз өзүбүздүн класс эмнени чече алабыз деген үмүттө болдук. Бул ачык-айкын болгон жана дагы бир нерсе келсе, чоң ката бизге айтып берет.

Uнегизги класс келишими туунду класс тарабынан аткарылбашы үчүн, базалык класстын методун жокко чыгарган класс. 

Методдорду чакырууга же биздин келишимге туура келбеген объекттердеги талааларга кирүүгө аракет жасоону каалабайбыз. Бизде тамга басылганда, келишим аны менен аныкталган. Файл классынын талаалары жана методдору. Эми бизде эч нерсе жок болгондуктан, биз каалаган нерсени, жипти да жөнөтө алабыз, натыйжада, ката кетириши мүмкүн.

Акыркы натыйжа эки учурда бирдей болсо да, код бузулат дегенди билдирет, биринчиси жакшы кабарды чыгарды. Бирок, бул абдан караңгы. Өзгөрүлмө деген эмне экенин билүүнүн эч кандай жолу жок – биздин учурда сап – жана кандай касиеттер изделип, табылган жок. Көйгөйдү оңдоо жана оңдоо кыйын. Программист Progress классын ачып, окуп, түшүнүшү керек. Келишим, бул учурда, сиз түрүн так көрсөтпөсөңүз, болуп саналат defiПрогресстин жүрүм-туруму менен аныкталды. Бул Прогресске гана белгилүү болгон кыйыр келишим. Биздин мисалда ушундай defigetAsPercent() методунда жөнөтүлгөн жана узундуктагы эки талаага жетүү менен аяктады. Чыныгы жашоодо болжолдонгон келишим абдан татаал жана класста бир нече секунд издеп табуу кыйын болушу мүмкүн.

Төмөндөгү башка кеңештердин бири да оңой эле ишке ашырылбаса же күч-аракетти талап кылбаган олуттуу архитектуралык өзгөрүүлөргө дуушар болгондо гана, ушул чечим сунуш кылынат.

Ercole Palmeri

Инновациялык бюллетень
Инновация боюнча эң маанилүү жаңылыктарды өткөрүп жибербеңиз. Аларды электрондук почта аркылуу алуу үчүн катталыңыз.

акыркы макалалар

Veeam ransomware үчүн коргоодон баштап жооп кайтарууга жана калыбына келтирүүгө чейин эң комплекстүү колдоону камтыйт

Veeam тарабынан Coveware кибер опузалап инциденттерге жооп берүү кызматтарын көрсөтүүнү улантат. Coveware криминалистика жана ремедиация мүмкүнчүлүктөрүн сунуштайт ...

April 23 2024

Жашыл жана санариптик революция: алдын ала тейлөө мунай жана газ өнөр жайын кантип өзгөртөт

Болжолдуу тейлөө заводду башкарууга инновациялык жана жигердүү мамиле кылуу менен мунай жана газ секторун революция кылып жатат.…

April 22 2024

Улуу Британиянын монополияга каршы жөнгө салуучу органы GenAI боюнча BigTech коңгуроосун көтөрөт

Улуу Британиянын CMA жасалма интеллект рыногунда Big Tech жүрүм-туруму жөнүндө эскертүү берди. Ал жерде…

April 18 2024

Casa Green: Италияда туруктуу келечек үчүн энергетикалык революция

Имараттардын энергетикалык натыйжалуулугун жогорулатуу үчүн Европа Биримдиги тарабынан иштелип чыккан "Case Green" Декрети өзүнүн мыйзам чыгаруу процессин аяктады ...

April 18 2024

Инновацияны өз тилиңизде окуңуз

Инновациялык бюллетень
Инновация боюнча эң маанилүү жаңылыктарды өткөрүп жибербеңиз. Аларды электрондук почта аркылуу алуу үчүн катталыңыз.

бизди ээрчи