Məqalələr

SOLID prinsipinə görə açıq / qapalı

Proqram subyektləri (siniflər, modullar, funksiyalar və s.) Genişləndirmə üçün açıq, lakin redaktə üçün qapalıdır.

Təxmini oxuma vaxtı: 7 minuti

Proqramın dizaynı: modullar, siniflər və funksiyalar elə bir şəkildə qurulsun ki, yeni funksionallığa ehtiyac olduqda mövcud kodu dəyişdirməyək, əksinə mövcud kod tərəfindən istifadə ediləcək yeni kod yazaq. Bu, xüsusilə Java, C, C ++ və ya C # kimi dillərlə qəribə səslənə bilər, burada yalnız mənbə kodunun özünə deyil, ikili sənədə də aiddir. Mövcud ikili faylların, icra olunan sənədlərin və ya DLL-lərin yenidən bölüşdürülməsini tələb etməyən yollarla yeni xüsusiyyətlər yaratmaq istəyirik.
SOLID kontekstində OCP

Tamamlayıcı SRP və OCP

Bir modulun dəyişdirilməsi üçün yalnız bir səbəb olması lazım olduğunu söyləyən Tək Məsuliyyət SRP prinsipini artıq gördük. OCP və SRP prinsipləri bir-birini tamamlayır. SRP prinsipinə uyğun olaraq hazırlanmış kod, OCP prinsiplərinə də hörmət göstərəcəkdir. Dəyişmək üçün yalnız bir səbəbi olan kodumuz olduqda, yeni bir xüsusiyyət təqdim etmək bu dəyişiklik üçün ikinci dərəcəli bir səbəb yaradacaqdır. Beləliklə, həm SRP, həm də OCP pozulacaqdı. Eynilə, yalnız əsas funksiyası dəyişdikdə dəyişməli olan və yeni funksionallıq əlavə edildikdə dəyişməz qalmalı, beləliklə OCP-yə hörmət edən bir kodumuz varsa, daha çox SRP-yə də hörmət göstərəcəkdir.
Bu, SRP-nin hər zaman OCP-yə aparması və ya əksinə olması demək deyil, əksər hallarda onlardan birinə riayət edilərsə, ikincisinə nail olmaq olduqca sadədir.

OCP prinsipinin pozulması nümunəsi

Tamamilə texniki baxımdan Açıq / Qapalı prinsip çox sadədir. Aşağıdakı kimi iki sinif arasındakı sadə bir əlaqə OCP prinsipini pozur.

İstifadəçi sinfi birbaşa Məntiq sinifindən istifadə edir. İkinci bir Məntiq sinifini həm cari, həm də yenisini istifadə etməyimizə imkan verən bir şəkildə tətbiq etməyimiz lazımdırsa, mövcud Məntiq sinifinin dəyişdirilməsi lazımdır. İstifadəçi birbaşa məntiqin həyata keçirilməsinə bağlıdır, indiki vəziyyətə təsir etmədən yeni məntiq təqdim etməyimizin yolu yoxdur. Və statik olaraq yazılmış dillərdən bəhs etdiyimiz zaman, İstifadəçi sinifinin də dəyişiklik tələb etməsi ehtimalı yüksəkdir. Tərtib olunmuş dillərdən danışsaq, şübhəsiz ki, həm istifadəçi tərəfindən yürütülə bilən, həm də məntiqlə icra edilə bilən və ya dinamik kitabxananın yenidən tərtib edilməsi və çatdırılması tələb ediləcək, mümkün olduqda qarşısını almaq lazımdır.

Əvvəlki sxemə istinad edərək, başqa bir sinfi birbaşa istifadə edən hər hansı bir sinifin Açıq / Qapalı prinsipinin pozulmasına səbəb ola biləcəyini çıxara bilərik. 
Fərz edək ki, tətbiqimiz vasitəsilə yüklənmiş bir sənədin "faizlə" irəliləməsini təmin edə bilən bir sinif yazmaq istəyirik. İki əsas sinifimiz olacaq, bir irəliləyiş və bir fayl və mən bunları aşağıdakı kimi istifadə etmək istədiyimizi düşünürəm:

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

Bu kodda biz Progress istifadəçiləriyik. Həqiqi fayl ölçüsündən asılı olmayaraq faiz nisbətində bir dəyər əldə etmək istəyirik. Məlumat mənbəyi olaraq File istifadə edirik. Faylın uzunluğu bayt və yükləyiciyə göndərilən məlumat miqdarını təmsil edən göndərilən bir sahə var. Bu dəyərlərin tətbiqetmədə necə yenilənməsini maraqlandırmırıq. Bunu bizim üçün edən bir sehrli məntiq olduğunu düşünə bilərik, buna görə bir testdə onları açıq şəkildə qura bilərik.

class File {
     public $length;
     public $sent;
}

Fayl sinfi iki sahəni ehtiva edən sadə bir məlumat obyektidir. Əlbəttə ki, fayl adı, yol, nisbi yol, cari qovluq, növ, icazələr və s. Kimi digər məlumat və davranışları da ehtiva etməlidir.

class Progress {

     private $file;

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

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

}

Tərəqqi sadəcə bir qurucuda bir sənəd qəbul edən bir sinifdir. Aydınlıq üçün konstruktor parametrlərində dəyişkən tipi göstərdik. Progress, getAsPercent () üzərində göndərilən dəyərləri və uzunluğu Fayldan götürüb yüzdə birinə çevirəcək bir faydalı metod var. Sadə və işləyir.

Bu kod düzgün görünür, lakin Açıq / Qapalı prinsipini pozur.

Bəs niyə?

Və necə?

Tələbləri dəyişdirməyə çalışaq

Hər bir tətbiq zaman keçdikcə inkişaf etmək üçün yeni xüsusiyyətlərə ehtiyac duyacaq. Tətbiqimiz üçün yeni bir xüsusiyyət, faylları yükləmək əvəzinə musiqi axınına icazə vermək ola bilər. Faylın uzunluğu baytlarla, musiqinin müddəti saniyələrlə təmsil olunur. Dinləyicilərimizə bir inkişaf çubuğu təklif etmək istəyirik, amma yuxarıda yazılan sinfi təkrar istifadə edə bilərikmi?

İnnovasiya bülleteni
Yeniliklərlə bağlı ən vacib xəbərləri qaçırmayın. Onları e-poçtla almaq üçün qeydiyyatdan keçin.

Xeyr. Bizim irəliləməyimiz Fayla bağlıdır. Yalnız musiqi məlumatlarını idarə edə bilər, baxmayaraq ki musiqi məzmununa da tətbiq oluna bilər. Ancaq bunu etmək üçün onu dəyişdirməliyik, tərəqqinin musiqisini və sənədlərini bilməliyik. Dizaynımız OCP-yə uyğun gəlsəydi, File və ya Progress-ə toxunmamız lazım olacaqdı. Mövcud irəliləyişdən təkrar istifadə edib musiqiyə tətbiq edə bilərik.

Mümkün həll yolu

Dinamik olaraq yazılmış dillər, iş vaxtı obyekt növlərini idarə etmək üstünlüyünə malikdir. Bu, tərtibat tərəqqisini konstruktordan çıxartmağa imkan verir və kod işləməyə davam edəcəkdir.

class Progress {

     private $file;

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

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

}

İndi Progress-də hər hansı bir şeyi başlata bilərik. Və hər hansı bir şəkildə, mən hərfi mənada bir şeyi nəzərdə tuturam:

class Music {

     public $length;
     public $sent;

     public $artist;
     public $album;
     public $releaseDate;

     function getAlbumCoverFile() {
         return 'Images/Covers/' . $this->artist . '/' . $this->album . '.png';
     }
}

Və yuxarıdakı kimi Musiqi sinfi mükəmməl işləyəcəkdir. Faylla çox oxşar bir testlə asanlıqla test edə bilərik.

function testItCanGetTheProgressOfAMusicStreamAsAPercent() {

     $music = new Music();
     $music->length = 200;
     $music->sent = 100;

     $progress = new Progress($music);

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

Beləliklə, hər hansı bir ölçülə bilən məzmun Progress sinfi ilə istifadə edilə bilər. Bəlkə dəyişən adını da dəyişdirərək onu kodlaşdırmalıyıq:

class Progress {

     private $measurableContent;

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

     function getAsPercent() {
          return $this->measurableContent->sent * 100 / $this->measurableContent->length;
     }

}

Faylı tip nişanı kimi göstərdiyimiz zaman, sinifimizin nəyin öhdəsindən gələ biləcəyinə nikbin baxdıq. Aydın idi və başqa bir şey gəlsəydi, böyük bir səhv bizə xəbər verərdi.

Uəsas sinif müqaviləsinin əldə edilmiş sinif tərəfindən yerinə yetirilməməsi üçün bir əsas sinif metodunu ləğv edən bir sinif. 

Metodlarımızı axtarmağa və ya müqaviləmizə uyğun olmayan obyektlərdə sahələrə daxil olmağa çalışmaq istəmirik. Nömrə olduğumuz zaman müqavilə onunla müəyyənləşdirildi. Fayl sinfinin sahələri və metodları. Artıq heç bir şeyimiz olmadığı üçün bir şey, hətta bir simli də göndərə bilərik və bu da səhv bir səhvlə nəticələnə bilər.

Son nəticə hər iki halda eyni olsa da, yəni kodun pozulması deməkdir, birincisi gözəl bir mesaj verdi. Ancaq bu, çox qaranlıqdır. Dəyişənin nə olduğunu – bizim vəziyyətimizdə sətir – və hansı xassələrin axtarıldığını və tapılmadığını bilmək üçün heç bir yol yoxdur. Problemi aradan qaldırmaq və həll etmək çətindir. Proqramçı Progress sinfini açmalı, oxumalı və başa düşməlidir. Müqavilə, bu halda, siz açıq şəkildə yazı işarəsini göstərmədiyiniz zaman, belədir defiTərəqqinin davranışı ilə nəticələndi. Bu, yalnız Tərəqqiyə məlum olan nəzərdə tutulan müqavilədir. Bizim nümunəmizdə belədir defigetAsPercent() metodunda göndərilən və uzunluqlu iki sahəyə daxil olmaqla əldə edilir. Real həyatda nəzərdə tutulan müqaviləni sinifdə bir neçə saniyə axtarmaqla çox mürəkkəb və tapmaq çətin ola bilər.

Bu həll yalnız aşağıdakı digər tövsiyələrin heç biri asanlıqla həyata keçirilə bilməyəcəyi təqdirdə və ya səy göstərməyən ciddi memarlıq dəyişikliklərinə səbəb olarsa tövsiyə olunur.

Continua leggendo il terzo principio della sostituzione di Liskow —>

Əlaqədar Oxumalar

Ercole Palmeri

İnnovasiya bülleteni
Yeniliklərlə bağlı ən vacib xəbərləri qaçırmayın. Onları e-poçtla almaq üçün qeydiyyatdan keçin.

Articoli recenti

Davamlılığın dörd sütunu

Davamlılıq termini indi müəyyən bir resursun qorunmasına yönəlmiş proqramları, təşəbbüsləri və hərəkətləri göstərmək üçün geniş istifadə olunur.

15 May 2024

Excel-də məlumatları necə birləşdirmək olar

İstənilən biznes əməliyyatı hətta müxtəlif formalarda çoxlu məlumat istehsal edir. Bu məlumatları Excel vərəqindən əl ilə daxil edin...

14 May 2024

Cisco Talos rüblük təhlili: cinayətkarlar tərəfindən hədəflənən korporativ e-poçtlar İstehsalat, Təhsil və Səhiyyə ən çox təsirlənən sektorlardır

Şirkət e-poçtlarının güzəşti 2024-cü ilin ilk üç ayında ilin son rübü ilə müqayisədə iki dəfədən çox artdı ...

14 May 2024

Interface segregation prinsipi (ISP), dördüncü SOLID prinsipi

İnterfeyslərin ayrılması prinsipi obyekt yönümlü dizaynın beş SOLID prinsipindən biridir. Bir sinifdə olmalıdır…

14 May 2024

Yaxşı bir təhlil üçün Excel-də məlumat və düsturları ən yaxşı şəkildə necə təşkil etmək olar

Microsoft Excel verilənlərin təhlili üçün istinad alətidir, çünki məlumat dəstlərini təşkil etmək üçün bir çox funksiyalar təklif edir,…

14 May 2024

İki mühüm Walliance Equity Crowdfunding layihəsi üçün müsbət nəticə: Jesolo Wave Island və Milano Via Ravenna

Walliance, SİM və 2017-ci ildən bəri Daşınmaz Əmlak Crowdfunding sahəsində Avropanın liderləri arasında olan platforma, tamamlandığını elan edir ...

13 May 2024

Filament nədir və Laravel Filamentindən necə istifadə olunur

Filament bir neçə tam yığın komponenti təmin edən "sürətləndirilmiş" Laravel inkişaf çərçivəsidir. Bu prosesi asanlaşdırmaq üçün nəzərdə tutulmuşdur...

13 May 2024

Süni intellektlərin nəzarəti altında

“Mən təkamülü başa çatdırmaq üçün geri qayıtmalıyam: özümü kompüterin içində layihələndirəcəyəm və saf enerjiyə çevriləcəyəm. Bir dəfə məskunlaşan…

10 May 2024

İnnovasiyaları öz dilinizdə oxuyun

İnnovasiya bülleteni
Yeniliklərlə bağlı ən vacib xəbərləri qaçırmayın. Onları e-poçtla almaq üçün qeydiyyatdan keçin.

bizi izləyin