Asılılığın inversiya prinsipi. Asılılığın inversiya prinsipinə tənqidi baxış

ev / Biznes planları

Əslində, bütün prinsiplər MƏKTƏK Onlar bir-biri ilə sıx bağlıdır və onların əsas məqsədi yüksək keyfiyyətli, genişlənə bilən proqram təminatı yaratmağa kömək etməkdir. Ancaq son prinsip MƏKTƏK həqiqətən onların fonunda fərqlənir. Əvvəlcə bu prinsipin formuluna nəzər salaq. Belə ki, asılılığın inversiya prinsipi (Asılılığın inversiya prinsipi - DIP): “Abstraksiyalardan asılılıq. Konkret nədənsə asılılıq yoxdur”.. Proqram təminatının inkişafı sahəsində tanınmış mütəxəssis Robert Martin də prinsipi vurğulayır DIP və onu sadəcə olaraq başqa prinsiplərə əməl etməyin nəticəsi kimi təqdim edir MƏKTƏK— açıq/qapalı prinsip və Liskov əvəzetmə prinsipi. Xatırladaq ki, birincisi deyir ki, sinif yeni dəyişikliklərin tətbiqi üçün dəyişdirilməməlidir, ikincisi isə varisliyə aiddir və proqramın düzgün işləməsinə müdaxilə etmədən bəzi əsas tipli törəmə növlərin təhlükəsiz istifadəsini nəzərdə tutur. Robert Martin əvvəlcə bu prinsipi aşağıdakı kimi formalaşdırdı:

1). Daha yüksək səviyyələrdəki modullar aşağı səviyyələrdəki modullardan asılı olmamalıdır. Hər iki səviyyədəki modullar abstraksiyalardan asılı olmalıdır.

2). Abstraksiyalar detallardan asılı olmamalıdır. Detallar abstraksiyalardan asılı olmalıdır.

Yəni siniflər onların konkret həyata keçirilməsinə deyil, abstraksiyalara görə inkişaf etdirilməlidir. Və prinsiplərə əməl etsəniz OCPLSP, onda biz məhz buna nail olacağıq. Beləliklə, dərsə bir az qayıdaq. Orada nümunə olaraq sinfi nəzərdən keçirdik Bard, ilk əvvəl ciddi şəkildə siniflə bağlı idi Gitara, müəyyən bir musiqi alətini təmsil edir:

ictimai sinif Bard ( şəxsi Gitara gitara; ictimai Bard(Guitar gitara) ( this.guitar = guitar; ) public void play() ( guitar.play(); ) )

ictimai sinif Bard (

şəxsi gitara gitara;

ictimai bard (gitara gitara)

bu. gitara = gitara;

ictimai boşluq oyunu()

gitara oynamaq();

Bu sinfə başqa musiqi alətləri üçün dəstək əlavə etmək istəsək, bu sinfi bu və ya digər şəkildə dəyişdirməli olardıq. Bu, prinsipin açıq şəkildə pozulmasıdır OCP. Və yəqin ki, siz artıq fikir vermisiniz ki, bunlar da prinsipin pozulmasıdır DIP, çünki bizim vəziyyətimizdə abstraksiyamız detallardan asılı oldu. Sinifimizin daha da genişlənməsi baxımından bu heç də yaxşı deyil. Sinifimiz prinsipin şərtlərinə cavab versin deyə OCP sistemə interfeys əlavə etdik Alət musiqi alətlərinin müəyyən növlərini təmsil edən xüsusi siniflər tərəfindən həyata keçirilmişdir.

Fayl Alət.java:

İctimai interfeys Aləti (void play(); )

ictimai interfeys Aləti (

boş oyun();

Fayl Guitar.java:

sinif Gitara alətləri aləti( @Override public void play() ( System.out.println("Play Guitar!"); ) )

sinif Gitara alətləri Alət (

@Dəyişdir

ictimai boşluq oyunu()

Sistem. həyata. println("Gitara çal!");

Fayl Lute.java:

ictimai sinif Lute Aləti həyata keçirir( @Override public void play() ( System.out.println("Play Lute!"); ) )

ictimai sinif Lute Aləti həyata keçirir (

@Dəyişdir

ictimai boşluq oyunu()

Sistem. həyata. println("Lut çalın!");

Bundan sonra sinfi dəyişdik Bard, belə ki, lazım gələrsə, tətbiqləri tam olaraq ehtiyacımız olanlarla əvəz edə bilək. Bu, yaradılmış sistemə əlavə çeviklik təqdim edir və onun birləşməsini azaldır (siniflərin bir-birindən güclü asılılığı).

ictimai sinif Bard ( şəxsi Alət aləti; ictimai Bard() ( ) ictimai void play() ( instrument.play(); ) ictimai void setInstrument(Alət aləti) ( this.instrument = alət; ) )

ictimai sinif Bard (

şəxsi alət aləti;

, çoxluq interfeyslər və asılılığın çevrilməsi. Hər dəfə kod yazdığınız zaman sizə rəhbərlik etməli olan beş çevik prinsip.

SOLID prinsiplərindən hər hansı birinin digərindən daha vacib olduğunu söyləmək ədalətsizlik olardı. Bununla belə, ola bilsin ki, heç bir başqa prinsip kodunuza Asılılığın İnversiya Prinsipi və ya qısaca DIP kimi dərhal və dərin təsir göstərə bilməz. Əgər başqa prinsipləri başa düşmək və tətbiq etməkdə çətinlik çəkirsinizsə, ondan başlamalısınız, sonra qalanını artıq asılılığın inversiya prinsipinə əməl edən koda tətbiq etməlisiniz.

Tərif

A. Yüksək səviyyəli modullar aşağı səviyyəli modullardan asılı olmamalıdır. Onların hamısı abstraksiyalardan asılı olmalıdır.
B. Abstraksiyalar detallardan asılı olmamalıdır. Detallar abstraksiyalardan asılı olmalıdır.

Biz kodumuzu bu nömrələr əsasında təşkil etməyə çalışmalıyıq və burada bu işdə kömək edə biləcək bir neçə üsul var. Funksiyaların maksimum uzunluğu dörd sətirdən (başlıq daxil olmaqla beş) çox olmamalıdır, belə ki, onlar tamamilə zehnimizə uyğunlaşa bilsinlər. Girintilər beş səviyyədən çox olmamalıdır. Beşdən çox olmayan üsullarla dərslər. Dizayn nümunələrində istifadə olunan siniflərin sayı adətən beş ilə doqquz arasında dəyişir. Yuxarıdakı yüksək səviyyəli arxitekturamızda dörd-beş konsepsiya var. Beş SOLID prinsipi var ki, onların hər biri nümunələr üçün beş-doqquz konsepsiya/modul/sinif tələb edir. İdeal inkişaf komandası ölçüsü beş ilə doqquz arasındadır. Bir şirkətdəki komandaların ideal sayı da beş ilə doqquz arasındadır.

Gördüyünüz kimi, sehrli yeddi rəqəm, üstəgəl mənfi iki hər yerdə var, bəs kodunuz niyə fərqli olmalıdır?

2 cavab

Yaxşı sual - inversiya sözü bir qədər təəccüblüdür (çünki DIP tətbiq edildikdən sonra aşağı səviyyəli asılılıq modulu indi daha yüksək səviyyəli zəng edən moduldan asılı deyil: ya zəng edən, ya da asılı olan şəxs artıq əlavə abstraksiya vasitəsilə daha sərbəst birləşir. ).

Sual oluna bilər ki, mən niyə “inversiya” sözünü işlədirəm. Ədalətli olmaq üçün bunun səbəbi, strukturlaşdırılmış təhlil və dizayn kimi daha ənənəvi proqram təminatının inkişaf etdirilməsi üsullarının yüksək səviyyəli modulların aşağı səviyyəli modullardan asılı olduğu və abstraksiyaların təfərrüatlardan asılı olduğu proqram strukturları yaratmağa meyllidir. Əslində bu metodların məqsədlərindən biri yüksək səviyyəli modulların aşağı səviyyəli modullara necə zənglər etdiyini təsvir edən alt proqram iyerarxiyasını müəyyən etməkdir... Beləliklə, yaxşı tərtib edilmiş obyekt yönümlü proqramın asılılıq strukturu " adətən ənənəvi prosessual metodların nəticəsi olan asılılıq strukturuna nisbətən ters çevrilmişdir.

Bob dayının DIP-dəki məqaləsini oxuyarkən diqqət yetirməli bir məqam budur ki, C++ interfeysi yoxdur (və yazı zamanı, yoxdur), ona görə də C++ dilində bu abstraksiyaya nail olmaq adətən abstrakt/saf virtual baza sinfi vasitəsilə həyata keçirilir, halbuki Java və ya C#-da birləşmənin boşaldılması üçün mücərrədlik adətən interfeysi asılılıqdan çıxarmaqla və daha yüksək səviyyəli modul(lar)ı interfeysə birləşdirməklə ayrılır.

Redaktə et Sadəcə aydınlaşdırmaq üçün:

"Bəzi yerdə mən bunun asılılıq inversiyasını da görürəm"

İnversiya: Tətbiqdən konteynerə asılılıq idarəçiliyinin çevrilməsi (məsələn, Spring).

Asılılıq enjeksiyonu:

Zavod şablonu yazmaq əvəzinə, obyekti birbaşa müştəri sinfinə yeritmək necədir. Beləliklə, müştəri sinfi interfeysə müraciət etsin və biz müştəri sinfinə konkret bir növü daxil edə bilək. Bununla müştəri sinfinin yeni açar sözdən istifadə etməsinə ehtiyac qalmır və konkret siniflərdən tamamilə ayrıdır.

Nəzarətin İnversiyasi (IoC) haqqında nə demək olar?

Ənənəvi proqramlaşdırmada biznes məntiqinin axını bir-birinə statik olaraq təyin edilmiş obyektlərlə müəyyən edilir. İdarəetmənin tərsinə çevrilməsi ilə axın assembler nümunəsi tərəfindən yaradılan və abstraksiyalar vasitəsilə müəyyən edilmiş obyekt qarşılıqlı əlaqəsi ilə mümkün olan obyekt qrafikindən asılıdır. Bağlama prosesi asılılıq inyeksiyası vasitəsilə əldə edilir, baxmayaraq ki, bəziləri xidmət lokatorundan istifadənin idarəetmənin inversiyasını da təmin etdiyini iddia edir.

Nəzarətin dizayn bələdçisi kimi çevrilməsi aşağıdakı məqsədlərə xidmət edir:

  • Müəyyən bir tapşırığın icrasından onun həyata keçirilməsinin ayrılması var.
  • Hər bir modul nəyi nəzərdə tutduğuna diqqət yetirə bilər.
  • Modullar digər sistemlərin nə etdiyi barədə heç bir fərziyyə irəli sürmür, lakin onların müqavilələrinə əsaslanır.
  • Modulların dəyişdirilməsi digər modullara təsir etmir.

Ətraflı məlumat üçün bax.

Dependency inversion ən vacib proqramlaşdırma deyimlərindən biridir. Rusdilli İnternetdə bu idiomun (prinsipin) təsviri təəccüblü dərəcədə azdır. Buna görə də təsvir etməyə cəhd etmək qərarına gəldim. Nümunələri Java-da edəcəyəm; bu, mənim üçün daha asandır, baxmayaraq ki, asılılığın inversiya prinsipi hər hansı bir proqramlaşdırma dilinə tətbiq olunur.

Bu təsvir Vladimir Matveev ilə birlikdə Java dilini öyrənən tələbələrlə dərslərə hazırlıq zamanı hazırlanmışdır.

Bu seriyadan digər məqalələr:

"Asılılıq" anlayışının tərifindən başlayım. Asılılıq nədir? Əgər kodunuz daxili olaraq hansısa sinifdən istifadə edirsə və ya hansısa sinfin və ya funksiyanın statik metodunu açıq şəkildə çağırırsa, bu, asılılıqdır. İcazə verin misallarla izah edim:

Aşağıda, A sinfi someMethod() adlı metod daxilində açıq şəkildə B sinifinin obyektini yaradır və onun metodunu someMethodOfB() adlandırır.

İctimai sinif A ( void someMethod() ( B b = new B(); b.someMethodOfB(); ) )

Eynilə, məsələn, B sinfi Sistem sinifinin statik sahələrinə və metodlarına açıq şəkildə daxil olur:

İctimai sinif B ( void someMethodOfB() ( System.out.println("Salam dünya"); ) )

Bütün hallarda, hər hansı bir sinif (A növü) müstəqil olaraq hər hansı bir sinif (B növü) yaratdıqda və ya statik sahələrə və ya sinif üzvlərinə açıq şəkildə daxil olduqda, bu adlanır. düz asılılıq. Bunlar. vacibdir: əgər öz daxilindəki sinif öz daxilində başqa bir siniflə işləyirsə, bu, asılılıqdır. Əgər o da öz daxilində bu sinfi yaradırsa, bu düz asılılıq.

Birbaşa asılılıqlarda səhv nədir? Birbaşa asılılıqlar pisdir, çünki müstəqil olaraq öz daxilində başqa sinif yaradan sinif bu sinfə “sıx” bağlıdır. Bunlar. açıq şəkildə B = new B(); , onda A sinfi həmişə B sinfi ilə işləyəcək və başqa sinif yoxdur. Və ya System.out.println("..."); sonra sinif həmişə System.out-a çıxış edəcək və başqa heç bir yerdə.

Kiçik siniflər üçün asılılıqlar dəhşətli deyil. Bu kod olduqca yaxşı işləyə bilər. Ancaq bəzi hallarda, A sinifinizin müxtəlif siniflər mühitində universal işləyə bilməsi üçün siniflərin digər tətbiqlərini - asılılıqları tələb edə bilər. Bunlar. Məsələn, sizə B sinfi yox, eyni interfeysə malik başqa bir sinif lazımdır və ya System.out yox, məsələn, loggerə çıxış (məsələn, log4j).

Birbaşa əlaqə qrafik olaraq aşağıdakı kimi göstərilə bilər:

Bunlar. kodunuzda A sinfi yaratdığınız zaman: A a = new A(); əslində, yalnız bir A sinfi deyil, asılı siniflərin bütöv bir iyerarxiyası yaradılır, bunun nümunəsi aşağıdakı şəkildədir. Bu iyerarxiya “sərtdir”: ayrı-ayrı siniflərin mənbə kodunu dəyişmədən siz iyerarxiyadakı siniflərdən heç birini əvəz edə bilməzsiniz. Buna görə də, belə bir tətbiqdə A sinfi dəyişən mühitə zəif uyğunlaşır. Çox güman ki, onu yazdığınız xüsusi koddan başqa heç bir kodda istifadə etmək olmaz.

A sinfini xüsusi asılılıqlardan ayırmaq üçün istifadə edin asılılıq inyeksiyası. Asılılıq inyeksiyası nədir? Kodda tələb olunan sinfi açıq şəkildə yaratmaq əvəzinə, asılılıqlar konstruktor vasitəsilə A sinfinə ötürülür:

İctimai sinif A ( özəl final B b; ictimai A(B b) ( this.b = b; ) ictimai etibarsız someMethod() ( b.someMethodOfB(); ) )

Bu. A sinfi indi öz asılılığını konstruktor vasitəsilə alır. İndi A sinfini yaratmaq üçün ilk növbədə onun asılı sinfini yaratmalısınız. Bu halda B:

B b = yeni B(); A a = yeni A(b); a.someMethod();

Eyni prosedur bütün siniflər üçün təkrarlanırsa, yəni. D sinifinin nümunəsini B sinifinin konstruktoruna, onun E və F asılılıqlarını D sinifinin konstruktoruna və s. ötürsəniz, bütün asılılıqların tərs qaydada yaradıldığı kodu alacaqsınız:

G g = yeni G(); H h = yeni H(); F f = yeni (g,h); E e = yeni E(); D d = yeni D(e,f); B b = yeni B(d); A a = yeni A(b); a.someMethod();

Bunu qrafik olaraq belə göstərmək olar:

2 şəkli müqayisə etsəniz - yuxarıdakı birbaşa asılılıqları olan şəkil və asılılıq inyeksiyalı ikinci şəkil - oxların istiqamətinin əksinə dəyişdiyini görə bilərsiniz. Bu səbəbdən idioma asılılıqların “inversiya”sı adlanır. Başqa sözlə, asılılığın inversiyası o deməkdir ki, sinif öz-özünə asılılıq yaratmır, onları konstruktorda yaradılmış formada (və ya başqa şəkildə) qəbul edir.

Asılılığın çevrilməsi niyə yaxşıdır? Asılılığın inversiyası ilə siz onun kodunu dəyişmədən sinifdəki bütün asılılıqları əvəz edə bilərsiniz. Bu o deməkdir ki, A sinifiniz ilkin yazıldığı proqramdan başqa başqa proqramda istifadə üçün çevik şəkildə konfiqurasiya edilə bilər. Bu. Asılılığın inversiya prinsipi (bəzən asılılığın inyeksiyası prinsipi də adlanır) çevik, modul, təkrar istifadə edilə bilən kodun qurulması üçün açardır.

Asılılıq inyeksiyasının dezavantajı da ilk baxışdan görünür - bu nümunədən istifadə edərək hazırlanmış siniflərin obyektlərinin qurulması çox əmək tələb edir. Buna görə də, asılılıq inyeksiyası adətən bu tapşırığı asanlaşdırmaq üçün nəzərdə tutulmuş bəzi kitabxanalarla birlikdə istifadə olunur. Məsələn, Google Guice kitabxanalarından biri. Santimetr. .

Asılılığın inversiya prinsipinin formalaşdırılması iki qaydadan ibarətdir, bunlara əməl olunması kod strukturuna son dərəcə müsbət təsir göstərir:

  • Üst səviyyə modulları aşağı səviyyəli modullardan asılı olmamalıdır. Hər ikisi abstraksiyadan asılı olmalıdır.
  • abstraksiyalar detallardan asılı olmamalıdır. Detallar abstraksiyalardan asılı olmalıdır.

Əvvəlcə çox cəlbedici görünmür və oxucu yəqin ki, çoxlu terminlər, mürəkkəb nitq fiqurları və onsuz da heç nə aydın olmayan nümunələrlə çox darıxdırıcı bir məqaləyə hazırdır. Ancaq boş yerə, çünki, prinsipcə, asılılığın inversiya prinsipinə tabe olaraq, hər şey yenidən düzgün istifadəyə və əsas ideya kontekstində - kodun təkrar istifadəsi ilə bağlıdır.

Burada aktual olacaq başqa bir anlayış növlərin zəif birləşməsidir, yəni onların bir-birindən asılılığını azaltmaq və ya aradan qaldırmaqdır ki, bu da əslində abstraksiya və polimorfizmdən istifadə etməklə əldə edilir. Bu, əslində, asılılığın inversiya prinsipinin mahiyyətidir.

İndi boş birləşmənin hərəkətdə necə göründüyünü aydın şəkildə nümayiş etdirəcək bir nümunəyə baxaq.

Deyək ki, ad günü tortu sifariş etmək qərarına gəldik. Bunun üçün küçənin küncündə yerləşən gözəl çörək sexinə getdik. Bizim üçün yüksək səslə “Lüks” adı ilə tort bişirə biləcəklərini bildik və müsbət cavab aldıqdan sonra sifariş verdik. Bu sadədir.

İndi gəlin bu koda hansı abstraksiyaların daxil edilməsinə qərar verək. Bunu etmək üçün özünüzə bir neçə sual verin:

  • Niyə tort? Siz həmçinin tort və ya keks sifariş edə bilərsiniz
  • Niyə xüsusi olaraq ad gününüz üçün? Bəs toy və ya məzuniyyət olsaydı?
  • Niyə “Lüks”, “Anthill” və ya “Prague”ni daha çox bəyənsəm necə olar?
  • Niyə şəhərin mərkəzində və ya başqa yerdə şirniyyat mağazası yox, məhz bu çörək sexi?

Və bu “əgər” və “əgər” hər biri kodun genişlənməsinin tələb olunduğu nöqtələrdir və müvafiq olaraq, abstraksiyalar vasitəsilə boş birləşmə və növlərin müəyyən edilməsi.

İndi növlərin özlərini qurmağa başlayaq.

Sifariş verə biləcəyimiz hər hansı qənnadı məmulatları üçün interfeys müəyyən edəcəyik.

IPastry interfeysi ( sətir adı (almaq; təyin etmək; ) )

Və burada xüsusi bir tətbiq, bizim vəziyyətimiz üçün - doğum günü tortu. Gördüyünüz kimi, ad günü tortu ənənəvi olaraq şamdan ibarətdir)))

Class BirthdayCake: IPastry ( public int NumberOfCandles ( get; set; ) public string Name ( get; set; ) public override string ToString() ( return String.Format("(0) with (1) candle nices", Name, NumberOfCandles )))

İndi toy üçün və ya sadəcə çay üçün tort lazımdırsa və ya kekslər və ya kremli tortlar istəsək, hər kəs üçün əsas interfeysimiz var.

Növbəti sual qənnadı məmulatlarının bir-birindən necə fərqlənməsidir (təbii ki, adından başqa). Əlbəttə ki, reseptlə!

Və reseptin konsepsiyasına inqrediyentlərin siyahısı və yemək prosesinin təsviri daxildir. Beləliklə, tərkib anlayışı üçün ayrıca interfeysimiz olacaq:

Interface IIInqredient ( string IngredientName ( get; set;) double Quantity ( get; set; ) string Units ( get; set; ) )

Və tortumuz üçün inqrediyentlər: un, yağ, şəkər və qaymaq:

Sinif Un:IIQrediyent ( ictimai sətir TərkibiAdı ( almaq; təyin etmək; ) ümumi ikiqat Miqdar ( almaq; təyin; ) ictimai sətir Vahidlər ( almaq; təyin etmək; ) ictimai sətir Keyfiyyət ( almaq; təyin etmək; ) ) sinif Yağ: II Tərkibi ( ictimai sətir TərkibiName ( almaq; təyin etmək; ) ictimai ikiqat Miqdar ( almaq; təyin etmək; ) ictimai sətir Vahidlər ( almaq; təyin etmək; ) ) sinif Şəkər: IITərkibi ( ictimai sətir TərkibiAdı ( almaq; təyin etmək; ) ictimai ikiqat Miqdar ( almaq; təyin etmək; ) ictimai sətir Vahidlər ( almaq; təyin etmək; ) ictimai sətir Növ ( almaq; təyin etmək; ) ) ) sinif Krem: II Tərkibi ( ictimai sətir TərkibiName ( almaq; təyin etmək; ) ümumi ikiqat Miqdar ( almaq; təyin etmək; ) ümumi sətir Vahidlər ( almaq; təyin etmək; ) ictimai ikiqat yağ (almaq; təyin etmək; ))

Tərkiblərin siyahısı müxtəlif reseptlərdə və müxtəlif qənnadı məmulatlarında fərqlənə bilər, lakin bizim reseptimiz üçün bu siyahı kifayətdir.

İndi resept konsepsiyasına keçməyin vaxtıdır. Nə bişirsək də, hər halda onun nə adlandığını, nə olduğunu, yeməyin tərkibinə hansı maddələrin daxil olduğunu və necə bişiriləcəyini bilirik.

İnterfeys IRRecipe ( Tip PastryType ( almaq; set; ) sətir adı ( almaq; set;) IList Tərkibi ( get;set;) sətir Təsviri ( get;set;) )

Xüsusilə, ad günü tortu reseptini təmsil edən sinif belə görünür:

Class BirthdayCakeRecipe: IRRecipe ( ictimai Növ PastryType ( almaq; set; ) ictimai sətir Adı ( almaq; set;) ictimai IList Tərkibi ( almaq; set; ) ictimai sətir Təsvir ( almaq; set; ) ictimai BirthdayCakeReipe() ( Tərkibi = yeni Siyahı (); } }

İndi küçənin küncündəki gözəl çörək seximizə keçək.

Əlbəttə ki, bir çox başqa çörək sexlərinə müraciət edə bilərik, ona görə də bunun üçün əsas interfeys müəyyən edəcəyik. Çörək üçün ən vacib şey nədir? Məhsulları bişirmək bacarığı.

İnterfeys IBakery (IPastry Bake(IRRecipe resepti); )

Çörəkxanamızı təmsil edən sinif budur:

NiceBakeryOnTheCornerOFMyStreet sinfi ( Lüğət menyu = yeni Lüğət (); public void AddToMenu(IRRecipe resepti) ( if (!menu.ContainsKey(recipe.Name)) ( menu.Add(recipe.Name, resept); ) else ( Console.WriteLine("O, artıq menyudadır"); ) ) ictimai IRRecipe FindInMenu(sətir adı) ( əgər (menu.ContainsKey(ad)) ( qaytarma menyusu; ) Console.WriteLine("Bağışlayın...hazırda bizdə " + adı yoxdur); null qaytarın; ) ictimai IPastry Bake (IRResept resepti) ( əgər (resept != null) ( IPastry pastry = Activator.CreateInstance(recipe.PastryType) IPastry kimi; if (pastry != null) ( pastry.Name = resept.Name; pastry IPastry kimi qaytarın; ) ) null qaytar ;))

Yalnız kodu sınamaq qalır:

Sinif Proqramı ( static void Main() ( //çörəkçilik sinfinin inctance yaradılması var bakery = new NiceBakeryOnTheCornerOFMyStreet(); //resept üçün inqrediyentlərin hazırlanması var un = new Flour() ( IngredientName = "Un", Miqdarı = 1,5 , Vahid = "kq" ); var kərə yağı = yeni Kərə yağı() ( TərkibiAdı = "Kərə yağı", Miqdarı = 0,5, Vahid = "kq" ); var şəkər = yeni Şəkər() ( Tərkibi Adı = "Şəkər", Miqdarı = 0,7 , Vahidlər = "kq" ); var krem ​​= yeni Krem() ( TərkibiAdı = "Krem", Miqdarı = 1.0, Vahidlər = "litr" ); //və bu reseptin özü var WeddingCakeRecipe = new BirthdayCakeRecipe() ( PastryType = typeof(BirthdayCake), Ad = "Birthday Cake Luxury", Təsvir = "gözəl ad günü tortunun necə hazırlanacağı haqqında təsvir" ); WeddingCakeRecipe.Ingredients.Add(un); WeddingCakeRecipe.Ingredients.Add(kərə yağı); WeddingCakeRecipe.Ingredients .Əlavə (şəkər); WeddingCakeRecipe.Tərkibi.Əlavə(krem); //tort reseptimizin çörək sexinin menyu çörəkxanasına əlavə edilməsi.AddToMenu(weddingCakeRecipe); //indi sifariş edək!! Ad günü tortu = bakery.Bake(bakery.FindInMenu("Birthday Cake Luxury")) BirthdayCake kimi; //bir neçə şam əlavə edirik;) tort.NumberOfCandles = 10; //və biz buradayıq !!! Console.WriteLine(tort); ) )

İndi bütün koda yenidən baxaq və onu qiymətləndirək. Kod olduqca sadədir, növlər, onların abstraksiyaları, verilənlər və funksionallıq aydın şəkildə təsvir edilmişdir, kod genişləndirməyə və təkrar istifadəyə imkan verir. Hər bir seqment ağrısız şəkildə əsas tipə uyğun olan digəri ilə əvəz edilə bilər və bu, kodun qalan hissəsini pozmayacaq.

Siz sonsuz inqrediyent növlərini, müxtəlif növ qənnadı məmulatları üçün reseptlər əlavə edə, çörəkxanaları, qənnadı məmulatlarını və digər oxşar müəssisələri təsvir edən digər siniflər yarada bilərsiniz.

Pis nəticə deyil. Və hamısı dərsləri bir-biri ilə minimal şəkildə əlaqələndirməyə çalışdığımız üçün təşəkkür edirik.

İndi asılılığın inversiya prinsipinin pozulmasının nəticələri haqqında düşünək:

  1. sərtlik (sistemdə hər hansı bir dəyişiklik etmək çox çətin olardı, çünki hər bir dəyişiklik onun bir çox müxtəlif hissələrinə təsir etdi).
  2. kövrəklik (sistemin bir hissəsinə hər hansı bir dəyişiklik edildikdə, onun digər hissələri həssas olur və bəzən bu, ilk baxışdan çox aydın görünmür).
  3. hərəkətsizlik (modullar bir-birinə güclü şəkildə bağlı olduğundan, kodun digər sistemlərdə təkrar istifadəsini unuda bilərsiniz).

Yaxşı, indi kodda asılılığın inversiya prinsipinin nə qədər faydalı olduğu barədə öz nəticənizi çıxarın. Məncə cavab aydındır.

© 2023 youmebox.ru -- Biznes haqqında - Faydalı biliklər portalı