Maqolalar

SOLID tamoyiliga binoan ochiq / yopiq

Dasturiy ta'minot sub'ektlari (sinflar, modullar, funktsiyalar va boshqalar) kengaytirilishi uchun ochiq bo'lishi kerak, ammo tahrirlash uchun yopiq bo'lishi kerak.

Dasturiy ta'minotni loyihalash: modullar, sinflar va funktsiyalar, agar yangi funksiyalar zarur bo'lganda, biz mavjud kodni o'zgartirmasligimiz kerak, aksincha mavjud kod ishlatadigan yangi kod yozamiz. Bu g'alati tuyulishi mumkin, ayniqsa Java, C, C ++ yoki C # kabi tillarda, bu nafaqat manba kodining o'zi, balki ikkilik uchun ham amal qiladi. Mavjud ikkilik fayllarni, bajariladigan fayllarni yoki DLL-larni qayta taqsimlashni talab qilmaydigan usullar bilan yangi xususiyatlarni yaratmoqchimiz.
SOLID kontekstidagi OCP

 

SRP va OCP qo'shimcha

Modulni o'zgartirish uchun faqat bitta sabab bo'lishi kerakligi to'g'risida yagona mas'uliyatning SRP printsipini ko'rib chiqdik. OCP va SRP tamoyillari bir-birini to'ldiradi. SRP printsipiga muvofiq ishlab chiqilgan kod, shuningdek, OCP printsiplarini hurmat qiladi. O'zgarish uchun faqat bitta sababga ega bo'lgan kod mavjud bo'lsa, yangi xususiyatni kiritish ushbu o'zgarish uchun ikkinchi darajali sababni yaratadi. Shunday qilib, ikkala SRP va OCP buzilgan bo'ladi. Xuddi shunday, agar bizda faqat uning asosiy funktsiyasi o'zgarganda o'zgarishi kerak bo'lgan va yangi funktsiyalar qo'shilganda o'zgarishsiz qoladigan kod mavjud bo'lsa, shuning uchun OCP-ni hurmat qiladigan bo'lsak, u asosan SRP-ni ham hurmat qiladi.
Bu SRP har doim OCPga olib borishini yoki aksincha degani emas, aksariyat hollarda ulardan biri bajarilgan bo'lsa, ikkinchisiga erishish juda oddiy.

 

OCP printsipining buzilishiga misol

Faqatgina texnik nuqtai nazardan, Ochiq / Yopiq printsip juda oddiy. Ikki sinf o'rtasidagi oddiy munosabatlar, quyida keltirilganlar singari, OCP printsipini buzadi.

Foydalanuvchi sinfi to'g'ridan-to'g'ri Mantiq sinfidan foydalanadi. Agar biz ikkinchi mantiq sinfini hozirgi va yangisidan foydalanishga imkon beradigan tarzda amalga oshirishimiz zarur bo'lsa, mavjud mantiq sinfini o'zgartirishimiz kerak bo'ladi. Foydalanuvchi to'g'ridan-to'g'ri mantiqni amalga oshirishga bog'liq, bizda yangi mantiqni hozirgi holatga ta'sir qilmasdan taqdim etishning iloji yo'q. Va statik usulda yozilgan tillar haqida gapiradigan bo'lsak, foydalanuvchi sinfi ham modifikatsiyani talab qilishi mumkin. Agar biz kompilyatsiya qilingan tillar haqida gapiradigan bo'lsak, albatta foydalanuvchi tomonidan bajariladigan va mantiqiy bajariladigan dastur yoki dinamik kutubxona qayta kompilyatsiya qilishni va etkazib berishni talab qiladi, iloji boricha undan qochish kerak.

Oldingi sxemaga murojaat qilib, biz to'g'ridan-to'g'ri boshqa sinfdan foydalanadigan har qanday sinf Open / Closed printsipining buzilishiga olib kelishi mumkin degan xulosaga kelishimiz mumkin. 
Keling, o'z dasturimiz orqali yuklab olingan faylning "foizda" bajarilishini ta'minlaydigan sinf yozishni xohlaymiz. Bizda ikkita asosiy sinf, ya'ni "Progress" va "File" bo'ladi va menimcha, ulardan quyidagicha foydalanishni xohlaymiz:

 

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

Ushbu kodda biz Progress foydalanuvchilarmiz. Faylning haqiqiy hajmidan qat'i nazar, foiz sifatida qiymat olishni istaymiz. Axborot manbai sifatida biz Fayldan foydalanamiz. Faylning bayt uzunligi va yuborilgan deb nomlangan maydon mavjud bo'lib, u yuklab oluvchiga yuborilgan ma'lumotlar miqdorini ifodalaydi. Ilovada ushbu qiymatlar qanday yangilanishi bizga ahamiyat bermaydi. Buni biz uchun sehrli mantiq bor deb taxmin qilishimiz mumkin, shuning uchun testda biz ularni aniq belgilashimiz mumkin.

 

sinf fayli {
     umumiy $ uzunligi;
     ommaviy $ yuborilgan;
}

 

Fayl sinfi bu ikkita maydonni o'z ichiga olgan oddiy ma'lumotlar ob'ekti. Albatta, u boshqa ma'lumotlar va xatti-harakatlarni o'z ichiga olishi kerak, masalan, fayl nomi, yo'l, nisbiy yo'l, joriy katalog, tur, ruxsatlar va boshqalar.

 

Sinf taraqqiyoti {

     shaxsiy $ fayli;

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

     funktsiyasi getAsPercent () {
          qaytarish $ this-> file-> sent * 100 / $ this-> file-> length;
     }

}

Progress - bu shunchaki faylni konstruktorida qabul qiladigan sinf. Aniqlik uchun biz konstruktor parametrlarida o'zgaruvchan turini aniqladik. Progress-da getAsPercent () bitta foydali usul mavjud, u yuborilgan qiymatlar va uzunlikni File-dan olib, ularni foizga aylantiradi. Oddiy va u ishlaydi.

Ushbu kod to'g'ri ko'rinadi, ammo u Open / Closed printsipini buzadi.

Lekin nega?

Va qanday?

 

Keling, talablarni o'zgartirishga harakat qilaylik

Vaqt o'tishi bilan rivojlanish uchun har bir dasturga yangi xususiyatlar kerak bo'ladi. Bizning dasturimiz uchun yangi xususiyat shunchaki fayllarni yuklab olish o'rniga musiqa oqimiga ruxsat berish bo'lishi mumkin. Faylning uzunligi baytlarda, musiqaning davomiyligi soniyalarda ifodalanadi. Biz tinglovchilarimizga rivojlanish satrini taklif qilmoqchimiz, lekin yuqorida yozilgan sinfni qayta ishlata olamizmi?

Yo'q, biz qila olmaymiz. Bizning rivojlanishimiz Fayl bilan bog'liq. U faqat fayl ma'lumotlarini boshqarishi mumkin, garchi u musiqiy tarkibga ham tegishli bo'lsa. Buning uchun biz uni o'zgartirishimiz kerak, biz Progress-ga musiqa va fayllarni bilib olishimiz kerak. Agar bizning dizaynimiz OCP-ga mos keladigan bo'lsa, biz File yoki Progress-ga tegmasligimiz kerak edi. Biz mavjud taraqqiyotni qayta ishlatib, uni musiqaga qo'llashimiz mumkin.

 

Innovatsion axborot byulleteni
Innovatsiyalar haqidagi eng muhim yangiliklarni o'tkazib yubormang. Ularni elektron pochta orqali olish uchun ro'yxatdan o'ting.

Mumkin bo'lgan echim

Dinamik ravishda terilgan tillar ish vaqtidagi ob'ekt turlarini boshqarishda afzalliklarga ega. Bu bizga Progress konstruktoridan tipfintni olib tashlashga imkon beradi va kod ishlashni davom ettiradi.

Sinf taraqqiyoti {

     shaxsiy $ fayli;

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

    funktsiyasi getAsPercent () {
         qaytarish $ this-> file-> sent * 100 / $ this-> file-> length;
     }

}

Endi Progress-da hamma narsani ishga tushirishimiz mumkin. Va har qanday narsa bilan, men tom ma'noda hamma narsani nazarda tutayapman:

sinf musiqasi {

umumiy $ uzunligi;
ommaviy $ yuborilgan;

jamoat $ artist;
umumiy $ albomi;
public $ releaseDate;

funktsiyasi getAlbumCoverFile () {
"Tasvirlar / Qopqoqlarni /" qaytarish $ this-> artist. '/'. $ this-> albom. '.png';
}
}

Va yuqoridagi kabi Musiqa sinfi mukammal ishlaydi. Biz uni Faylga juda o'xshash test yordamida osongina sinab ko'rishimiz mumkin.
function testItCanGetTheProgressOfAMusicStreamAsAPercent () {
$ music = new Music ();
$ music-> length = 200;
$ music-> sent = 100;

$ progress = new Progress ($ music);

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

Shunday qilib, har qanday o'lchovli tarkibni Progress klassi bilan ishlatish mumkin. Ehtimol, biz uni o'zgarmaydigan nomini o'zgartirib kod bilan ifodalashimiz kerak:

Sinf taraqqiyoti {

xususiy $ measureurableContent;

funktsiya __construct ($ measureurableContent) {
$ this-> measureurableContent = $ measureurableContent;
}

funktsiyasi getAsPercent () {
return $ this-> measureurableContent-> sent * 100 / $ this-> measureurableContent-> uzunlik;
}

}

Faylni shrift sifatida ko'rsatganimizda, biz sinfimiz nimani uddalay olishiga umid bog'ladik. Bu aniq edi va agar boshqa biron bir narsa bo'lsa, katta xato bizga aytib beradi.

Una sinf, bu asosiy sinf shartnomasi olingan sinf tomonidan bajarilmasligi uchun asosiy sinf usulini bekor qiladi. 

Biz usullarni chaqirishga yoki bizning shartnomamizga mos kelmaydigan ob'ektlardagi maydonlarga kirishga urinishni xohlamaymiz. Bizda tipografiya bo'lganida, shartnoma shu bilan belgilandi. Fayl sinfining maydonlari va usullari. Endi bizda hech narsa yo'q, biz har qanday narsani, hatto mag'lubiyatni ham yuborishimiz mumkin va bu xatoga olib keladi.

Yakuniy natija ikkala holatda ham bir xil bo'lsa-da, ya'ni kod buziladi, birinchisi yoqimli xabarni ishlab chiqardi. Biroq, bu juda qorong'i. O'zgaruvchining nima ekanligini bilishning hech qanday usuli yo'q - bizning holatlarimizda string - va qanday xususiyatlar qidirilgan va topilmagan. Muammoni tuzatish va tuzatish qiyin. Dasturchi Progress sinfini ochishi, uni o'qishi va tushunishi kerak. Shartnoma, bu holda, siz yozma ma'lumotni aniq ko'rsatmasangiz, shunday bo'ladi defiProgressning xatti-harakati bilan yakunlandi. Bu faqat Progressga ma'lum bo'lgan nazarda tutilgan shartnoma. Bizning misolimizda shunday defigetAsPercent() usulida yuborilgan va uzunlikdagi ikkita maydonga kirish orqali amalga oshiriladi. Haqiqiy hayotda nazarda tutilgan shartnoma juda murakkab va sinfda bir necha soniya qidirib topish qiyin bo'lishi mumkin.

Ushbu echim faqat quyida keltirilgan boshqa biron bir maslahatning hech biri osonlikcha amalga oshirilmasa yoki ular me'yoriy o'zgarishlarga olib kelmasa, kuch sarflashga imkon bermasa tavsiya etiladi.

Ercole Palmeri

Innovatsion axborot byulleteni
Innovatsiyalar haqidagi eng muhim yangiliklarni o'tkazib yubormang. Ularni elektron pochta orqali olish uchun ro'yxatdan o'ting.

So'nggi maqolalar

Buyuk Britaniyaning monopoliyaga qarshi regulyatori GenAI ustidan BigTech signalini oshiradi

Buyuk Britaniya CMA Big Tech kompaniyasining sun'iy intellekt bozoridagi xatti-harakatlari haqida ogohlantirish e'lon qildi. U yerda…

18 Aprel 2024

Casa Green: Italiyada barqaror kelajak uchun energiya inqilobi

Evropa Ittifoqi tomonidan binolarning energiya samaradorligini oshirish uchun ishlab chiqilgan "Yashil uylar" qarori qonunchilik jarayonini yakunladi ...

18 Aprel 2024

Casaleggio Associati tomonidan yangi hisobotga ko'ra, Italiyada elektron tijorat + 27%

Casaleggio Associati kompaniyasining Italiyada elektron tijorat bo'yicha yillik hisoboti taqdim etildi. “AI-Commerce: sun’iy intellekt bilan elektron tijoratning chegaralari” deb nomlangan hisobot.…

17 Aprel 2024

Yorqin g'oya: Bandalux havoni tozalovchi parda Airpure®-ni taqdim etadi

Doimiy texnologik innovatsiyalar va atrof-muhit va odamlar farovonligiga sodiqlik natijasi. Bandalux Airpure® chodirini taqdim etadi ...

12 Aprel 2024