Kontrolün Ters Çevrilmesi Nedir?


1826

Kontrolün İnversiyonu (IoC) ilk karşılaşıldığında oldukça kafa karıştırıcı olabilir.

  1. Bu ne?
  2. Hangi sorunu çözüyor?
  3. Ne zaman kullanılmalı, ne zaman kullanılmamalıdır?

292
Bu cevapların çoğundaki sorun kullanılan terminolojidir. Konteyner nedir? Ters çevirme? Bağımlılık? Büyük sözler olmadan layman terimleriyle açıklayınız.
kirk.burleson

13
Programmers.SE Ayrıca bakınız: Neden Kontrol Inversiyon yolu o adlandırılır?
Izkata

8
Bağımlılık Enjeksiyonu (DI) - Martin Fowlers'ın buradaki kirliliğine bakın: martinfowler.com/articles/injection.html#InversionOfControl
Ricardo Sanchez


Bu bir sıfat, bir isim değil, bir şey değil, akış kontrolünün kapsayıcıda değil, delegede olduğu kodda yapılan bir değişikliğin açıklamasıdır.
Martin Spamer

Yanıtlar:


1523

Kontrolün Ters Çevrilmesi (IoC) ve Bağımlılık Enjeksiyonu (DI) modelleri, kodlarınızdaki bağımlılıkları kaldırmakla ilgilidir.

Örneğin, uygulamanızın bir metin düzenleyici bileşeni olduğunu ve yazım denetimi sağlamak istediğinizi varsayalım. Standart kodunuz şöyle görünecektir:

public class TextEditor {

    private SpellChecker checker;

    public TextEditor() {
        this.checker = new SpellChecker();
    }
}

Burada yaptığımız şey, TextEditorile arasında bir bağımlılık yaratır SpellChecker. IoC senaryosunda bunun gibi bir şey yapardık:

public class TextEditor {

    private IocSpellChecker checker;

    public TextEditor(IocSpellChecker checker) {
        this.checker = checker;
    }
}

İlk kod örneğinde instantiating SpellChecker( this.checker = new SpellChecker();) yöntemini kullanıyoruz, yani TextEditorsınıf doğrudan sınıfa bağlıdır SpellChecker.

İkinci kod örneğinde, SpellCheckerbağımlılık sınıfını TextEditoryapıcı imzasında (sınıfta bağımlılığı başlatmayan) bir soyutlama yaratıyoruz . Bu, bağımlılığı çağırmamıza ve TextEditor sınıfına şu şekilde aktarmamıza izin verir:

SpellChecker sc = new SpellChecker; // dependency
TextEditor textEditor = new TextEditor(sc);

Şimdi TextEditorsınıfı oluşturan istemci SpellChecker, TextEditorimzaya bağımlılığı enjekte ettiğimiz için hangi uygulamanın kullanılacağını denetliyor .


50
İyi açık örnek. Bununla birlikte, ISpellChecker arabiriminin nesnenin yapıcısına iletilmesini gerektirmek yerine, bunu ayarlanabilir bir özellik (veya SetSpellChecker yöntemi) olarak gösterdik. Bu hala IoC'yi oluşturur mu?
devios1

25
chainguy1337 - evet olur. Bu gibi ayarlayıcıların kullanılması, yapıcı enjeksiyonunun aksine ayarlayıcı enjeksiyon olarak adlandırılır (her ikisi de bağımlılık enjeksiyon teknikleri). IoC oldukça genel bir kalıptır, ancak bağımlılık enjeksiyonu IoC'ye sahiptir
Jack Ukleja

257
Birçok oylamaya rağmen, bu cevap yanlış. Lütfen martinfowler.com/articles/injection.html#InversionOfControl adresine bakın . Özellikle, "Kontrolün Tersinmesi çok genel bir terimdir ve bu yüzden insanlar bunu kafa karıştırıcı buluyor.
Rogério

45
@Rogeria'ya katılıyorum. Bu da IoC denir ve ben ;-) kadar oy sayısına tarafından sürpriz neden açıklamıyor
Aravind Yarram

31
@Rogerio ve @Pangea ile beraberim. Bu, yapıcı enjeksiyonu için iyi bir örnek olabilir, ancak orijinal soruya iyi bir cevap olmayabilir. Fowler tarafından tanımlandığı gibi IoC, herhangi bir tür enjeksiyon kullanılmadan, örneğin bir servis bulucu veya hatta basit kalıtım kullanılarak gerçekleştirilebilir.
mtsz

642

Kontrol tersine çevirme, örneğin bir gui programı gibi program geri çağrılarınız olduğunda elde edeceğiniz şeydir.

Örneğin, eski bir okul menüsünde:

print "enter your name"
read name
print "enter your address"
read address
etc...
store in database

böylece kullanıcı etkileşimi akışını kontrol eder.

Bir GUI programında veya başka bir yerde, bunun yerine şunu söylüyoruz:

when the user types in field a, store it in NAME
when the user types in field b, store it in ADDRESS
when the user clicks the save button, call StoreInDatabase

Şimdi kontrol ters çevrildi ... kullanıcı girişini sabit bir sırayla kabul etmek yerine, kullanıcı verinin girilme sırasını ve verinin veritabanına kaydedilmesini kontrol eder.

Temel olarak, olay döngüsü, geri aramalar veya yürütme tetikleyicileri olan her şey bu kategoriye girer.


161
Bu adamı yere düşürme. teknik olarak doğru martinfowler.com/bliki/InversionOfControl.html IoC çok genel bir prensip. Kontrol akışı, bağımlılık enjeksiyonuyla "ters çevrilir", çünkü bazı harici sistemlere (örn. IoC kabı) bağımlılıkları etkili bir şekilde devredersiniz.
Jack Ukleja

38
Schneider'in yorumuyla aynı fikirde. 5 indirim? Zihin boğuk, çünkü gerçekten doğru olan tek cevap bu. Açılışa dikkat edin: ' gui programı gibi .' Bağımlılık enjeksiyonu, IoC'nin sadece en sık görülen gerçekleştirilmesidir.
Jeff Sternal

40
Gerçekten de, bu birkaç doğru aniden biri! Çocuklar, IoC temel olarak bağımlılıklar ile ilgili değil . Bir şey değil.
Rogério

13
+1 - Bu, Martin Fowler'ın aşağıdaki ifadesinin iyi bir açıklamasıdır (örnek olarak) - "Erken kullanıcı arayüzleri uygulama programı tarafından kontrol edilir." Ad girin "," adres girin "gibi bir dizi komutunuz olur; program istemleri yönlendirir ve her birine bir yanıt alır.Grafik (hatta ekran tabanlı) UI'lerle UI çerçevesi bu ana döngüyü içerecek ve programınız bunun yerine ekrandaki çeşitli alanlar için olay işleyicileri sağlayacaktır. program ters çevrildi, sizden çerçeveye taşındı. "
Ashish Gupta

14
Şimdi neden bazen "Hollywood Prensibi: Bizi arama, seni arayacağız" olarak
anılıyor

419

Kontrolün Ters Çevrilmesi Nedir?

Bu basit iki adımı izlerseniz, kontrolü tersine çevirdiniz:

  1. Ayrı neyi gelen kısmını to-do zaman parçasını to-do.
  2. Emin olun zaman parçası olarak bilir Little'ın hakkında mümkün olduğunca neyi parçası; ve tam tersi.

Uygulamanız için kullandığınız teknolojiye / dile bağlı olarak bu adımların her biri için mümkün olan birkaç teknik vardır.

-

İnversiyon Kontrol Inversion (IOC) bir parçası kafa karıştırıcı şeydir; çünkü inversiyon göreceli terimdir. IoC'yi anlamanın en iyi yolu bu kelimeyi unutmaktır!

-

Örnekler

  • Olay işleme. Olay İşleyicileri (yapılacaklar bölümü) - Olayları Yükseltme (ne zaman yapılacaklar bölümü)
  • Arabirimler. Bileşen istemcisi (ne zaman yapılacaklar bölümü) - Bileşen Arayüzü uygulaması (yapılacaklar bölümü)
  • Ünite fikstürü. Kurulum ve TearDown (yapılacaklar bölümü) - xUnit çerçeveleri başlangıçta Kur'a, sonunda TearDown'a (ne zaman yapılacaklar)
  • Şablon yöntemi tasarım deseni. şablon yöntemi ne zaman yapılacaklar bölümü - ilkel alt sınıf uygulaması yapılacaklar bölümü
  • COM içinde DLL konteyner yöntemleri. DllMain, DllCanUnload, vb (yapılacaklar bölümü) - COM / OS (ne zaman yapılacaklar bölümü)

Nasıl diyorsun Arayüzler. Bileşen istemcisi (ne zaman yapılacaklar bölümü) "when" (arayüzler) kullandığımız zaman mantıklı değil (Örn: Bağımlılık Enjeksiyonu), sadece özetliyoruz ve istemciye herhangi bir uygulama ekleme konusunda esneklik veriyoruz, ancak "when" yok işin içinde. Olay İşleme Olaylarını Artırma Durumunda "ne zaman" ile aynı fikirdeyim.
OldSchool

'Bileşen istemcisi' ile arayüzün kullanıcı / istemcisini kastediyorum. İstemci, 'ne yapmalı' bölümünü niyeti işlevselliği genişletmek isteyip istemediğini 'ne zaman' tetikleyeceğini bilir.
rpattabi

Martin Fowler'ın bu harika makalesine bir göz atın. Arayüzlerin kontrolün ters çevrilmesinin temel parçasını nasıl yaptığını gösterir: martinfowler.com/articles/injection.html#InversionOfControl
rpattabi

ilk iki cümle mükemmel. harika !! ne zaman yapmalı ve ne yapmalı mükemmel ayırma !! diğer cevapların neden bu kadar çok oy aldığını bilmiyorum. sadece anlamadan kodları konuşuyorlar.
Amir Ziarati

2
Ben açıklamayı seviyorum what-to-dovewhen-to-do
KimchiMan

164

Kontrollerin ters çevrilmesi endişeleri ayırmakla ilgilidir.

IoC olmadan : Bir dizüstü bilgisayarınız var ve ekranı yanlışlıkla bozuyorsunuz. Ve lanet olsun, aynı model dizüstü bilgisayar ekranının pazarda hiçbir yerde olmadığını görüyorsunuz. Yani sıkışıp kaldın.

IoC ile : Bir masaüstü bilgisayarınız var ve ekranı yanlışlıkla bozuyorsunuz. Piyasadaki hemen hemen her masaüstü monitörü yakalayabileceğinizi ve masaüstünüzle iyi çalıştığını görüyorsunuz.

Masaüstünüz bu durumda IoC'yi başarıyla uygular. Çeşitli monitörleri kabul eder, dizüstü bilgisayar kabul etmezken, düzeltmek için belirli bir ekrana ihtiyacı vardır.


1
@Luo Jiong Hui Nice açıklaması.
Sachin

3
Tasarım desenlerinin çoğu, hepsi olmasa da, günlük yaşamımızda çok iyi gördüğümüz ve anladığımız meslektaşlarına sahiptir. Bir tasarım modelini anlamanın en etkili yolu günlük yaşamdaki benzerlerini bilmektir. Ve inanıyorum ki çok kişi var.
Luo Jiong Hui

6
Yanlış cevap. IoC değil bağımlılık enjeksiyonunu açıklıyorsunuz . Yukarıdaki bu cevap hakkındaki
Rogério'nun yorumuna

2
Katılıyorum. Bu DI, IoC değil. Hala bir oylama yapıyor, çünkü bu basit bir yaklaşım, ancak konunun anlaşılmasını genişletmeye yardımcı oluyor.
MAR

Bağımlılık enjeksiyonunu açıklar. Ioc değil. Ama güzel ve net bir açıklama.
Chamin Wickramarathna

120

Kontrolün İnversiyonu (veya IoC) özgürlük kazanmakla ilgilidir (Evleniyorsunuz, özgürlüğü kaybettiniz ve kontrol ediliyorsunuz. Boşandınız, sadece Kontrolün İnversiyonunu uyguladınız. Buna "ayrıştırılmış" dedik. İyi bilgisayar sistemi çok yakın bir ilişkiyi önler.) daha fazla esneklik (Ofisinizdeki mutfak sadece temiz musluk suyuna hizmet eder, bu da içmek istediğinizde tek seçeneğinizdir. Patronunuz yeni bir kahve makinesi kurarak İnversiyon Kontrolü uyguladı. musluk suyu veya kahve seçme esnekliği.) ve daha az bağımlılık (Eşinizin bir işi var, bir işiniz yok, finansal olarak partnerinize bağlısınız, böylece kontrol altındasınız. Bir iş bulursunuz, Kontrolün Tersini uyguladınız. İyi bilgisayar sistemi bağımlılığı teşvik eder.)

Bir masaüstü bilgisayar kullandığınızda, köleleştirdiniz (veya söyleyin, kontrol ettiniz). Bir ekranın önünde oturmalı ve ona bakmalısınız. Yazmak için klavyeyi ve gezinmek için fareyi kullanın. Ve kötü yazılmış bir yazılım sizi daha da fazla köle edebilir. Masaüstünüzü bir dizüstü bilgisayarla değiştirirseniz, kontrolü tersine çevirirsiniz. Kolayca alıp hareket edebilirsiniz. Böylece, bilgisayarınızı kontrol etmek yerine, bilgisayarınızla nerede olduğunuzu kontrol edebilirsiniz.

Bir İnversiyon Kontrolü uygulayarak, bir yazılım / nesne tüketicisi, kontrol etmek veya daha az seçeneğe sahip olmak yerine, yazılım / nesneler üzerinde daha fazla kontrol / seçenek elde eder.

Yukarıdaki fikirleri göz önünde bulundurarak. IoC'nin önemli bir bölümünü hala özlüyoruz. IoC senaryosunda, yazılım / nesne tüketicisi karmaşık bir çerçevedir. Bu, oluşturduğunuz kodun kendi başınıza çağrılmadığı anlamına gelir. Şimdi bir web uygulaması için bu yolun neden daha iyi çalıştığını açıklayalım.

Kodunuzun bir grup çalışan olduğunu varsayalım. Bir araba inşa etmeleri gerekiyor. Bu işçilerin aracı inşa etmek için bir yere ve araçlara (yazılım çerçevesi) ihtiyaçları var. Bir geleneksel yazılım çerçevesi birçok araç ile bir garaj gibi olacak. Bu yüzden işçilerin kendileri bir plan yapmaları ve aracı inşa etmek için araçları kullanmaları gerekiyor. Bir araba yapmak kolay bir iş değildir, işçilerin düzgün bir şekilde planlaması ve işbirliği yapması gerçekten zor olacaktır. bir Modernyazılım çerçevesi tüm tesisler ve yöneticiler ile modern bir otomobil fabrikası gibi olacak. İşçilerin herhangi bir plan yapmasına gerek yoktur, yöneticiler (çerçevenin bir parçası, en zeki insanlardır ve en sofistike planı yapmışlardır), işçilerin ne zaman iş yapacaklarını bilmeleri için koordine yardımcı olacaktır (çerçeve kodunuzu çağırır). İşçilerin sadece yöneticilerin kendilerine verdiği araçları (Bağımlılık Enjeksiyonu kullanarak) kullanabilecek kadar esnek olmaları gerekir.

Her ne kadar işçiler projeyi en üst düzeyde yönetme kontrolünü yöneticilere vermesine rağmen (çerçeve). Ancak bazı profesyonellerin yardım etmesi iyidir. Bu IoC kavramı gerçekten geliyor.

MVC mimarisine sahip modern Web uygulamaları, URL Yönlendirmesi yapılacak çerçeveye bağlıdır ve çerçevenin çağırması için Denetleyicileri devreye sokar.

Bağımlılık Enjeksiyonu ve Kontrolün Ters Çevrilmesi ilişkilidir. Bağımlılık Enjeksiyonu mikro düzeydedir ve Kontrolün Ters Çevirilmesi makro düzeydedir. Bir yemeği bitirmek (IoC uygulamak) için her lokmayı yemek zorundasınız (DI uygulayın).


21
Ben evlilik DI ve boşanma IoC karşılaştırmak için oy verdi.
Marek Bar

"Her ne kadar işçiler projeyi en üst düzeyde yönetme kontrolünü yöneticilere vermesine rağmen (çerçeve). Ancak bazı profesyonellerin yardım etmeleri iyi. Bu IoC kavramı gerçekten geliyor." - Öncelikle kontrol Yöneticisi ile. Bu kontrolün nasıl ters çevrildiğini açıklayabilir misiniz? Profesyonellerin yardımıyla (ne tür bir profesyonel)? Nasıl ?
Istiaque Ahmed

@Istiaque Ahmed, işçilerin her şeyi tam olarak kontrol ettiği bir garaja kıyasla, modern otomobil fabrikasındaki yöneticiler üretimi kontrol ediyor. Şimdi işçiler kontrol etmek yerine kontrol ediliyor. Bu bağlamdaki yöneticiler, modern otomobil fabrikasının bir parçası, işçilerin bir parçası değil. Profesyoneller araba planlama ve yapımında profesyonel yöneticilerdir.
Luo Jiong Hui

2
Evli kişilere mesaj: boşanma, çocuk sınıflarınız da IoC uygulayabilir.
Julian

Evet, bu sadece evlilik hakkındaki vizyonum da IoC
balron

94

Inversion of Control'u kullanmadan önce, artıları ve eksileri olduğu gerçeğinin farkında olmalısınız ve bunu yaparsanız neden kullandığınızı bilmelisiniz.

Artıları:

  • Kodunuz birbirinden ayrılır, böylece bir arayüzün uygulamalarını alternatif uygulamalarla kolayca değiştirebilirsiniz
  • Uygulamalar yerine arabirimlere karşı kodlama için güçlü bir motivasyon kaynağıdır
  • Kodunuz için birim testleri yazmak çok kolaydır, çünkü yapıcısında / ayarlayıcılarında kabul ettiği nesnelerden başka bir şeye bağlı değildir ve bunları doğru nesnelerle izole ederek kolayca başlatabilirsiniz.

Eksileri:

  • IoC sadece programınızdaki kontrol akışını tersine çevirmekle kalmaz, aynı zamanda önemli ölçüde bulanıklaştırır. Bu, kodunuzu okuyamayacağınız ve bir yerden başka bir yere atlayamayacağınız anlamına gelir, çünkü normalde kodunuzda olacak bağlantılar artık kodda değildir. Bunun yerine, XML yapılandırma dosyalarında veya ek açıklamalarında ve bu meta verileri yorumlayan IoC kapsayıcınızın kodunda bulunur.
  • XML yapılandırmanızı veya ek açıklamalarınızı yanlış yaptığınız yeni bir hata sınıfı ortaya çıkar ve IoC kapsayıcınızın belirli koşullar altında nesnelerinizden birine neden boş bir başvuru enjekte ettiğini öğrenmek için çok zaman harcayabilirsiniz.

Şahsen IoC'nin güçlü noktalarını görüyorum ve onları gerçekten seviyorum ama mümkün olduğunda IoC'den kaçınma eğilimindeyim çünkü yazılımınızı artık "gerçek" bir program oluşturmayan, ancak sadece bir araya getirilmesi gereken bir şey sınıfına dönüştürüyor XML yapılandırması veya ek açıklama meta verileri ve onsuz parçalanır (ve düşer).


3
İlk con yanlış. İdeal olarak, kodunuzda yalnızca 1 IOC kapsayıcısı kullanılmalıdır ve bu ana yönteminizdir. Diğer her şey oradan aşağı basamaklı olmalıdır
mwjackson

23
Ne demek istediğini, sadece okuyamazsınız: myService.DoSomething () ve DoSomething tanımına gidin, çünkü IoC ile myService sadece bir arayüzdür ve bakmadığınız sürece gerçek uygulama sizin için bilinmemektedir. xml config dosyalarında veya ioc'nizin kurulumunun yapıldığı ana yöntemde.
chrismay

7
Resharper bu noktada yardımcı olur - arabirime karşı "tıklayın uygulamaya gidin". IoC'den (veya örneğinizden daha spesifik olarak
DI'den

10
Re: onsuz dışında artık "gerçek" programı ama ihtiyaçlar XML yapılandırması veya ek açıklama meta verilerine göre araya getirilmesi ve düşeceği (ve düşer) bu sadece bir şeyler oluşturduğunu sınıfların bir koleksiyon haline yazılım döner - Bu düşünüyorum çok yanıltıcı. Aynı şey bir çerçevenin üzerine yazılan herhangi bir program için de söylenebilir. İyi bir IoC kapsayıcısının farkı, programınız iyi tasarlanmış ve yazılmışsa, kodunuzu minimum düzeyde değiştirerek başka bir programa koyabilir veya IoC'yi tamamen atabilir ve nesnelerinizi elle yapılandırabilmenizdir. .
The Awnry Bear

7
Böyle gerçek bir cevap görmek güzel! Bu "IoC" kelimesi icat edilmeden önce, zaten arayüzler, fabrika modelleri, olay güdümlü modeller ve mantıklı olan yerlerde alay kullanan, nesne yönelimli tasarım ve TDD uygulamalarında rahat olan birçok deneyimli programcı olduğunu düşünüyorum. Ne yazık ki, çok fazla geliştirici / "mimar" tercih ettikleri çerçeveleri kullanmıyorsanız kötü uygulama iddia ediyorlar. Karmaşıklığın bir kısmı ile aynı hedefe ulaşmak için daha iyi bir tasarım, yerleşik dil kavramlarının ve araçlarının kullanılmasını tercih ediyorum, yani söylediğiniz gibi uygulamayı "bulanıklaştırmadan" :-)
Tony Wall

68
  1. Wikipedia Makalesi . Bana göre, kontrolün tersine çevrilmesi, sıralı olarak yazılan kodunuzu ve bir temsilci yapısına dönüştürmektir. Programınız her şeyi açıkça kontrol etmek yerine, programınız belirli şeyler olduğunda çağrılacak belirli işlevlere sahip bir sınıf veya kütüphane kurar.

  2. Kod çoğaltmayı çözer. Örneğin, eski günlerde sistem olay kitaplıklarını yeni olaylar için seçerek kendi olay döngünüzü el ile yazabilirsiniz. Günümüzde, çoğu modern API, sistem kitaplıklarına hangi olaylarla ilgilendiğinizi söyler ve ne zaman gerçekleşeceklerini size bildirir.

  3. Denetimi tersine çevirme, kod çoğaltmayı azaltmanın pratik bir yoludur ve kendinize bir yöntemin tamamını kopyalayıp kodun yalnızca küçük bir parçasını değiştirirseniz, denetimi ters çevirme ile mücadele etmeyi düşünebilirsiniz. Denetimin ters çevrilmesi delegeler, arayüzler ve hatta ham işlev işaretçileri kavramı aracılığıyla birçok dilde kolaylaşır.

    Her durumda kullanmak uygun değildir, çünkü bir programın akışını bu şekilde yazıldığında takip etmek daha zor olabilir. Yeniden kullanılacak bir kitaplık yazarken yöntemler tasarlamak için yararlı bir yöntemdir, ancak kod çoğaltma sorununu gerçekten çözmediği sürece kendi programınızın çekirdeğinde az miktarda kullanılmalıdır.


37
Wikipedia makalesinin çok kafa karıştırıcı olduğunu ve düzeltilmesi gerektiğini düşünüyorum. Gülmek için tartışma sayfasına göz atın.
devios1

Kendi olay döngünüzü yazmak yine de kontrolün ters çevrilmesi olabilir, eğer bu olay döngüsü bir çerçevenin yerini alıyorsa ve kodun geri kalanı kendi çerçevenizi yeni yazdığınız IoC ilkesini kullanıyorsa. Bu aslında kötü bir şey değil, sadece biraz daha fazla kodlamanın fiyatında okunabilirliği arttırıyor (her zaman uygun olduğu da değil).
lijat

45

Ama bence çok dikkatli olmalısın. Bu kalıbı aşırı kullanacaksanız, çok karmaşık bir tasarım ve daha da karmaşık bir kod yapacaksınız.

TextEditor ile bu örnekte olduğu gibi: sadece bir SpellChecker'ınız varsa IoC kullanmak gerçekten gerekli değildir? Birim testleri veya başka bir şey yazmanız gerekmedikçe ...

Neyse: makul ol. Tasarım deseni iyi uygulamalardır ancak vaaz edilecek İncil değildir. Her yere yapıştırmayın.


3
Sadece bir yazım denetçinizin olacağını nasıl anlarsınız?
İz

@Trace Örneğin, yazacağınız programın nasıl kullanılacağını biliyor olabilirsiniz. Yine de bağımlılık enjeksiyonu gibi bazı teknikler o kadar ucuzdur ki, böyle bir durumda bunları kullanmamanın nadiren bir nedeni vardır.
lijat

44

Bana göre IoC / DI, çağıran nesnelere bağımlılıkları bastırıyor. Çok basit.

Teknik olmayan yanıt, bir motoru açmadan hemen önce bir arabada değiştirebiliyor. Eğer her şey yolunda giderse (arayüz), iyisin.


44

Bir nesne olduğunuzu varsayalım. Ve bir restorana gidersiniz:

IoC olmadan : "elma" istersiniz ve daha fazlasını sorduğunuzda her zaman elma servis edilir.

IoC ile : "Meyve" isteyebilirsiniz. Her servisinizde farklı meyveler alabilirsiniz. örneğin elma, portakal veya karpuz.

Bu nedenle, çeşitleri sevdiğinizde IoC tercih edilir.


26
  1. Kontrolün ters çevrilmesi, sistemdeki bileşenlerin ve katmanların ayrıştırılması için kullanılan bir modeldir. Kalıp, bir bileşene yapıldığında bağımlılıkların enjekte edilmesiyle uygulanır. Bu bağımlılıklar genellikle daha fazla ayırma ve test edilebilirliği desteklemek için arayüzler olarak sunulur. Castle Windsor, Unity gibi IoC / DI kapları, IoC'nin sağlanması için kullanılabilecek araçlardır (kütüphaneler). Bu araçlar, ömür, AOP / Durdurma, politika vb. Gibi basit bağımlılık yönetiminin üstünde ve ötesinde genişletilmiş özellikler sağlar.

  2. a. Bir bileşenin bağımlılıklarını yönetmekten sorumlu olmasını azaltır.
    b. Farklı ortamlardaki bağımlılık uygulamalarını değiştirme yeteneği sağlar.
    c. Bir bileşenin bağımlılıkların alay edilmesiyle test edilmesini sağlar.
    d. Bir uygulama boyunca kaynakları paylaşmak için bir mekanizma sağlar.

  3. a. Test odaklı geliştirme yaparken kritiktir. IoC olmadan test etmek zor olabilir, çünkü test edilen bileşenler sistemin geri kalanıyla yüksek oranda bağlantılıdır.
    b. Modüler sistemler geliştirirken kritiktir. Modüler bir sistem, bileşenleri yeniden derleme gerektirmeden değiştirilebilen bir sistemdir.
    c. Kısmen bir kurumsal uygulamada ele alınması gereken birçok kesişen endişe varsa kritiktir.


2
Aslında, IoC esas olarak bağımlılıkları yönetmekle ilgili değildir. Lütfen martinfowler.com/articles/injection.html#InversionOfControl bölümüne bakınız . "Bağımlılık Enjeksiyonu adını aldı.
Rogério

26

Sadece ilk kısmı cevaplamak. Bu ne?

Denetimi Ters Çevirme (IoC), önce sınıfın bir örneğini ve ardından bağımlılık örnekleri oluşturan sınıf örneğini oluşturmak yerine, önce bir bağımlılığın örneklerini ve daha sonra bir sınıfın (isteğe bağlı olarak bunları yapıcı yoluyla enjekte etmek) oluşturmak anlamına gelir. Bu durumda, kontrol inversiyon tersine çevirir kontrol akışını programı. Yerine kontrol aranan ucun kontrol akışını (bağımlılıklar yaratırken), arayan programın kontrolü akışını kontrol eder .


Sınıf veya nesne oluşturma ile ilgili değil, bu martinfowler.com/articles/injection.html#InversionOfControl
Raghvendra Singh

22

Bu iki terimi basit bir şekilde anlayacağım:

For quick understanding just read examples*

Bağımlılık Enjeksiyonu (DI):
Bağımlılık enjeksiyonu genellikle , yöntemin bağımlı nesneyi yaratmasından ziyade, yöntemin bir yönteme parametre olarak bağlı olduğu bir nesnenin geçirilmesi anlamına gelir .
Uygulamada anlamı, yöntemin doğrudan belirli bir uygulamaya bağlı olmamasıdır; gereksinimleri karşılayan herhangi bir uygulama parametre olarak geçirilebilir.

Bu nesnelerle kendi bağımlılıklarını anlatın. Ve bahar onu mümkün kılar.
Bu gevşek bağlı uygulama geliştirmeye yol açar.

Quick Example:EMPLOYEE OBJECT WHEN CREATED,
              IT WILL AUTOMATICALLY CREATE ADDRESS OBJECT
   (if address is defines as dependency by Employee object)

Kontrolün Tersine Çevirme (IoC) Kabı:
Bu, çerçevelerin ortak bir özelliğidir, IOC , Java nesnelerini yönetir
- somutlaştırmadan BeanFactory'ye kadar yıkıma kadar.
-IC konteyneri tarafından başlatılan Java bileşenlerine fasulye denir ve IoC konteyneri bir fasulyenin kapsamını, yaşam döngüsü olaylarını ve yapılandırıldığı ve kodlandığı tüm AOP özelliklerini yönetir .

QUICK EXAMPLE:Inversion of Control is about getting freedom, more flexibility, and less dependency. When you are using a desktop computer, you are slaved (or say, controlled). You have to sit before a screen and look at it. Using keyboard to type and using mouse to navigate. And a bad written software can slave you even more. If you replaced your desktop with a laptop, then you somewhat inverted control. You can easily take it and move around. So now you can control where you are with your computer, instead of computer controlling it.

Bir İnversiyon Kontrolü uygulayarak, bir yazılım / nesne tüketicisi, kontrol etmek veya daha az seçeneğe sahip olmak yerine, yazılım / nesneler üzerinde daha fazla kontrol / seçenek elde eder.

Bir tasarım kılavuzu olarak kontrolün ters çevrilmesi aşağıdaki amaçlara hizmet eder:

Belirli bir görevin yürütülmesinin uygulamadan ayrılması söz konusudur.
Her modül tasarlandığı şeye odaklanabilir.
Modüller, diğer sistemlerin ne yaptığına dair herhangi bir varsayımda bulunmaz, ancak sözleşmelerine güvenir.
Modüllerin değiştirilmesinin diğer modüller üzerinde hiçbir yan etkisi yoktur
Burada işleri soyut tutacağım, konunun ayrıntılı anlaşılması için aşağıdaki bağlantıları ziyaret edebilirsiniz.
Örnekle iyi bir okuma

Detaylı açıklama


17

NilObject ile hemfikirim , ama buna eklemek istiyorum:

kendiniz bir yöntemin tamamını kopyalayıp kodun yalnızca küçük bir parçasını değiştirdiğinizi fark ederseniz, bunu kontrolün ters çevrilmesiyle başa çıkmayı düşünebilirsiniz.

Kendinizi kodu kopyalayıp yapıştırırken bulursanız, neredeyse her zaman yanlış bir şey yaparsınız . Bir kez ve Sadece Bir kez tasarım prensibi olarak kodlanmıştır .


17

Örneğin, görev # 1 nesne oluşturmaktır. IOC kavramı olmadan, görev # 1'in Programcı tarafından yapılması gerekiyordu.Ancak IOC kavramı ile görev # 1 konteyner tarafından yapılacaktı.

Kısacası Kontrol, Programcıdan konteynere çevrilir. Buna kontrolün ters çevrilmesi denir.

Burada iyi bir örnek buldum .


Bir kap, IoC'de, bağımlılıklar ("kullanıcı" nesnesi ve "kullanılmış" nesne arasındaki ilişkiler) ve nesne örnekleri de dahil olmak üzere nesne modelinin bulunduğu ve yönetildiği - ör. İçerilen bir kavramdır. Kap genellikle Spring gibi bir IoC çerçevesi tarafından sağlanır. Uygulamanızı oluşturan nesneler için bir çalışma zamanı havuzu olarak düşünün.
Awnry Bear

17

Bazı otellerde toplantı yaptığımızı söyleyelim.

Birçok insan, birçok su sürahisi, birçok plastik bardak.

Birisi içmek istediğinde bardağı doldurur, içer ve bardağı yere atar.

Bir saat sonra plastik bardak ve su ile kaplı bir zemine sahibiz.

Kontrolü tersine çevirelim.

Aynı yerde aynı toplantı, ama plastik bardaklar yerine bir bardak kaplı bir garsonumuz var (Singleton)

ve o her zaman içki misafirlerine sunuyor.

Birisi içmek istediğinde, garson bardağından alıp içer ve garsona geri döner.

Hijyenik soruyu bir kenara bırakarak, son içme süreci kontrol biçimi çok daha etkili ve ekonomiktir.

Ve bu tam olarak Bahar'ın (başka bir IoC kabı, örneğin: Guice) yaptığı şeydir. Spring IoC kapsayıcısı, yeni anahtar kelimeyi (plastik kap alarak) kullanarak uygulamanın ihtiyaç duyduğu şeyi yaratmasına izin vermek yerine, her zaman aynı nesnenin (singleton) gerekli nesnenin (tek bardak) uygulanmasını önerir.

Kendinizi böyle bir toplantının organizatörü olarak düşünün. Otel yönetimine mesaj atmanın yoluna ihtiyacınız var.

toplantı üyelerinin bir bardak suya ihtiyacı vardır, ancak çok kolay değildir.

Misal:-

public class MeetingMember {

    private GlassOfWater glassOfWater;

    ...

    public void setGlassOfWater(GlassOfWater glassOfWater){
        this.glassOfWater = glassOfWater;
    }
    //your glassOfWater object initialized and ready to use...
    //spring IoC  called setGlassOfWater method itself in order to
    //offer to meetingMember glassOfWater instance

}

Kullanışlı bağlantılar:-


singletons statik tip nesneler değil mi?
Gokigooooks

16

"IoC" ile ilgili kısaltma ve adı için en kafa karıştırıcı olan şey, bir ismin çok çekici olması - neredeyse bir gürültü adı.

Prosedürel ve olay güdümlü programlama arasındaki farkı tanımlamak için gerçekten bir isme ihtiyacımız var mı? Tamam, eğer ihtiyacımız varsa, ama çözdüğünden daha fazla kafa karıştırıcı yeni bir "hayattan daha büyük" bir isim seçmemiz gerekiyor mu?


1
IoC! = Olay güdümlü. Benzerlikler (ve bazı durumlarda çakışır), ancak temelde aynı paradigma değildir.
Awnry Bear

İyi soru. Olay güdümlü programlama kesinlikle IoC. Olay işleyicileri yazıyoruz ve bunlar olay döngüsünden çağrılıyor. Ancak IoC, Olay güdümlü programlamadan daha genel bir kavramdır. Alt sınıftaki bir yöntemi geçersiz kılarsanız, aynı zamanda bir çeşit IoC'dir. Uygun başvuru (örnek) kullanıldığında çağrılacak bir kod yazarsınız.
vi.su.

15

Kontrolün ters çevrilmesi , markete gittiğinizde ve eşiniz size satın alınacak ürünlerin listesini verir.

Programlama terimlerinde, getProductList()- - yürütmekte olduğunuz işleve bir geri çağırma işlevi geçti doShopping().

Fonksiyonun kullanıcının bazı kısımlarını tanımlamasını ve daha esnek olmasını sağlar.


5
Eşim genellikle benimle alışveriş yapar, ancak bu ifadeye katılıyorum.
ha9u63ar

1
@ ha9u63ar Karınız sizinle alışveriş yapıyor mu? Buna toplanma denir.
Julian

2
Parayı da verirse buna DI denir.
San

1
Ters (ters) kelimesi, karınız aradığında getProductList()para için kaynak bulmanız gerektiğinden, kontrolün sizin tarafınızda olduğu anlamına gelir. Ters çevirme durumunda, kontrol edecek, satın almayı sağlayacağı parayı da ifade edecek.
San

13

Burada 'kontrolün nasıl ters çevrildiğini' açıklayan çok net bir örnek buldum .

Klasik kod (Bağımlılık enjeksiyonu olmadan)

DI kullanmayan bir kod kabaca şöyle çalışacaktır:

  • Uygulama Foo'ya (örneğin bir kontrolör) ihtiyaç duyar, bu nedenle:
  • Uygulama Foo oluşturur
  • Uygulama çağrıları Foo
    • Foo'nun Bar'a (örneğin bir hizmete) ihtiyacı vardır, yani:
    • Foo Bar oluşturuyor
    • Foo Bar'ı çağırır
      • Bar'ın Bim'e (bir hizmet, bir depo,…) ihtiyacı var, yani:
      • Bar Bim'i yaratıyor
      • Bar bir şey yapar

Bağımlılık enjeksiyonunu kullanma

DI kullanan bir kod kabaca şu şekilde çalışacaktır:

  • Uygulama, Bim'e ihtiyaç duyan Bar'a ihtiyaç duyan Foo'ya ihtiyaç duyar, bu yüzden:
  • Uygulama Bim oluşturur
  • Uygulama Bar oluşturur ve Bim verir
  • Uygulama Foo oluşturur ve Bar verir
  • Uygulama çağrıları Foo
    • Foo Bar'ı çağırır
      • Bar bir şey yapar

Bağımlılıkların kontrolü, çağrılandan tersine çevrilir.

Hangi sorunları çözüyor?

Bağımlılık enjeksiyonu, enjekte edilen sınıfların farklı uygulamasıyla değiştirmeyi kolaylaştırır. Birim testi sırasında, testi çok daha kolay hale getiren sahte bir uygulama enjekte edebilirsiniz.

Örn: Uygulamanızın yüklenen kullanıcı dosyasını Google Drive'da sakladığını varsayalım, DI ile denetleyici kodunuz şöyle görünebilir:

class SomeController
{
    private $storage;

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

    public function myFunction () 
    {
        return $this->storage->getFile($fileName);
    }
}

class GoogleDriveService implements StorageServiceInterface
{
    public function authenticate($user) {}
    public function putFile($file) {}
    public function getFile($file) {}
}

Gereksinimleriniz değiştiğinde, GoogleDrive yerine Dropbox'ı kullanmanız istenir. StorageServiceInterface için yalnızca bir dropbox uygulaması yazmanız gerekir. Dropbox uygulaması StorageServiceInterface öğesine yapıştığı sürece denetleyicide herhangi bir değişiklik yapmazsınız.

Test sırasında, tüm yöntemlerin null (veya test gereksiniminize göre önceden tanımlanmış herhangi bir değer) döndürdüğü kukla uygulama ile StorageServiceInterface için alay oluşturabilirsiniz.

Bunun yerine, depolama nesnesini şu newanahtar sözcükle oluşturmak için controller sınıfınız varsa :

class SomeController
{
    private $storage;

    function __construct()
    {
        $this->storage = new GoogleDriveService();
    }

    public function myFunction () 
    {
        return $this->storage->getFile($fileName);
    }
}

Dropbox uygulamasıyla değiştirmek istediğinizde, newGoogleDriveService nesnesinin oluşturulduğu tüm satırları değiştirmeniz ve DropboxService'i kullanmanız gerekir. Ayrıca, SomeController sınıfını test ederken yapıcı her zaman GoogleDriveService sınıfını bekler ve bu sınıfın gerçek yöntemleri tetiklenir.

Ne zaman uygun ve ne zaman uygun değil? Bence bir sınıfın alternatif uygulamaları olduğunu (veya olabileceğini) düşündüğünüzde DI'yi kullanırsınız.


Bu en doğru cevap olmalı çünkü sadece “kontrol” ün nasıl ters çevrildiğini açıklıyor.
Yarimadam

şimdiye kadarki en iyi açıklama
Ali80

12

Çok basit bir yazılı açıklama burada bulunabilir

http://binstock.blogspot.in/2008/01/excellent-explanation-of-dependency.html

Diyor ki -

"Önemsiz herhangi bir uygulama, bir iş mantığı gerçekleştirmek için birbirleriyle işbirliği yapan iki veya daha fazla sınıftan oluşur. Geleneksel olarak, her nesne, birlikte çalıştığı nesnelere (onun bağımlılıklarına) kendi referanslarını almaktan sorumludur. DI uygularken, nesneler, sistemdeki her bir nesneyi koordine eden bir dış varlık tarafından oluşturma sırasında bağımlılıklarına verilir. Başka bir deyişle, bağımlılıklar nesnelere enjekte edilir. "


12

Bağımlılık Enjeksiyonu, bu ilkeyi nesne grafiği oluşturma için bir tasarım deseni olarak gerçekleştirirken (örn. Yapılandırma, nesnenin başka bir nesneye nasıl referans alınacağını kontrol etmek yerine nesnelerin birbirine nasıl başvurduğunu kontrol eder) kontrol eder.

Kontrolün İnversiyonuna bir tasarım deseni olarak baktığımızda, neleri tersine çevirdiğimize bakmamız gerekir. Bağımlılık Enjeksiyonu, nesnelerin grafiğini oluşturma kontrolünü tersine çevirir. Layman'ın döneminde söylenirse, kontrolün ters çevrilmesi, programdaki kontrol akışında değişiklik anlamına gelir. Örneğin. Geleneksel bağımsız uygulamada, kontrolün diğer üçüncü taraf kitaplıklarına geçtiği ana yöntemimiz var (üçüncü taraf kitaplığın işlevini kullanmamız durumunda), ancak kontrol kontrolünün ters çevrilmesi yoluyla üçüncü taraf kitaplık kodundan kodumuza aktarılır , üçüncü taraf kütüphanesinin hizmetini alıyoruz. Ancak, bir program içinde ters çevrilmesi gereken başka yönler de vardır - örneğin, kodu yürütmek için yöntemlerin ve iş parçacıklarının çağrılması.

Kontrolün İnversiyonu konusunda daha fazla derinlemesine ilgilenenler için bir tasarım deseni olarak Kontrolün İnversiyonunun daha eksiksiz bir resmini özetleyen bir makale yayınlandı (OfficeFloor: yazılım tasarımını geliştirmek için ofis desenlerini kullanma http://doi.acm.org/10.1145/ 2739011.2739013 , http://www.officefloor.net/about.html adresinden indirilebilir ücretsiz bir kopya ile ).

Tespit edilen şu ilişkidir:

Kontrolün Ters Çevrilmesi (yöntemler için) = Bağımlılık (durum) Enjeksiyonu + Devam Enjeksiyonu + Diş Enjeksiyonu

Mevcut İnversiyon Kontrolü için yukarıdaki ilişkinin özeti - http://dzone.com/articles/inversion-of-coupling-control


Bu çok açık bir cevap. Açıklama için teşekkürler.
KunYu Tsai

11

IoC, kodunuz ile üçüncü taraf kodu (kütüphane / çerçeve) arasındaki ilişkiyi tersine çevirmekle ilgilidir:

  • Normal yazılım geliştirmesinde, main () yöntemini yazar ve "library" yöntemlerini çağırırsınız. Kontrol sizde :)
  • IoC'de "çerçeve" main () öğesini kontrol eder ve yöntemlerinizi çağırır. Çerçeve kontrol altında :(

DI (Bağımlılık Enjeksiyonu), kontrolün uygulamada nasıl aktığıyla ilgilidir. Geleneksel masaüstü uygulaması, uygulamanızdan (main () yöntemi) diğer kütüphane yöntemi çağrılarına kontrol akışına sahipti, ancak DI kontrol akışı tersine çevrildiğinde, bu çerçeve uygulamanızı başlatmaya, başlatmaya ve gerektiğinde yöntemlerinizi çağırmaya özen gösterir.

Sonunda hep kazanırsın :)


10

Bu açıklamayı sevdim: http://joelabrahamsson.com/inversion-of-control-an-introduction-with-examples-in-net/

Basit başlar ve kod örneklerini de gösterir.

resim açıklamasını buraya girin

Tüketici X, bir şeyi başarmak için tüketilen Y sınıfına ihtiyaç duyar. Hepsi iyi ve doğal, ama X gerçekten Y kullandığını bilmeli mi?

X'in, davranışı kimin uyguladığını bilmeden Y'nin davranışına, yöntemlerine, özelliklerine vb. Sahip bir şey kullandığını bilmesi yeterli değil mi?

X tarafından Y'de kullanılan ve aşağıda I olarak gösterilen davranışın soyut bir tanımını çıkararak ve tüketici X'in Y yerine bunun bir örneğini kullanmasına izin vererek, Y hakkındaki özellikleri bilmeden yaptığı şeyi yapmaya devam edebilir.

resim açıklamasını buraya girin

Yukarıdaki çizimde Y, I ve X'in bir I örneğini kullanmaktadır. X'in hala Y'yi kullanması oldukça mümkündür, ancak ilginç olan X'in bunu bilmemesidir. Sadece I'yi uygulayan bir şey kullandığını biliyor.

Daha fazla bilgi ve aşağıdaki gibi avantajların açıklaması için makaleyi okuyun:

  • X artık Y'ye bağımlı değil
  • Daha esnek, uygulama zamanında kararlaştırılabilir
  • Kod biriminin izolasyonu, daha kolay test

...


Bağlantı çok yararlı. Gerçekten Teşekkürler :)
M Fuat NUROĞLU

10

Cevabın burada verildiğini anlıyorum. Ama yine de, kontrolün tersine çevrilmesi ile ilgili bazı temel bilgilerin, gelecekteki okuyucular için burada uzun süre tartışılması gerektiğini düşünüyorum.

Inversion of Control (IoC), Hollywood Prensibi adı verilen çok basit bir prensip üzerine inşa edilmiştir . Ve diyor ki,

Bizi arama, seni arayacağız

Bunun anlamı, rüyanızı yerine getirmek için Hollywood'a gitmeyin, eğer layıksanız, Hollywood sizi bulacak ve hayalinizi gerçekleştirecek. Oldukça ters çevrilmiş ha?

Şimdi IoC prensibi hakkında konuştuğumuzda, Hollywood'u unutmak için kullanıyoruz. IoC için üç unsur olmalı, bir Hollywood, siz ve hayalinizi gerçekleştirmek gibi bir görev.

Bizim programlama dünyasında, Hollywood'un (siz veya bir başkası tarafından yazılmış olabilir) genel çerçeveyi temsil sen yazdığın kullanıcı kodu ve temsil görevi size koduyla başarmak istediğiniz şeyi temsil eder. Artık görevinizi IoC'de değil, tek başınıza tetiklemeye gitmiyorsunuz! Aksine her şeyi çerçeveniz sizin görevinizi tetikleyecek şekilde tasarladınız. Böylece birini kahraman ya da diğerini kötü adam yapan yeniden kullanılabilir bir çerçeve inşa ettiniz. Ancak bu çerçeve her zaman sorumludur, birisini ne zaman seçeceğini ve birisinin sadece ne olmak istediğini bilir.

Burada gerçek bir hayat örneği verilecekti. Bir web uygulaması geliştirmek istediğinizi varsayalım. Böylece, bir web uygulamasının http isteğini işlemek, uygulama menüsü oluşturmak, sayfaları sunmak, çerezleri yönetmek, olayları tetiklemek vb.

Ve sonra, özel menü, sayfalar, çerezler veya bazı kullanıcı olaylarını vb. Oluşturmak için başka kodlar koyabileceğiniz bazı kancaları çerçevenizde bırakırsınız. Her tarayıcı isteğinde, çerçeveniz çalışır ve bağlanırsa özel kodlarınızı yürütür tarayıcıya.

Yani, fikir oldukça basit. Her şeyi kontrol edecek bir kullanıcı uygulaması oluşturmak yerine, önce her şeyi kontrol edecek, daha sonra özel kodlarınızı yazacak ve bunları zamanında yürütmek için çerçeveye bağlayacak yeniden kullanılabilir bir çerçeve oluşturursunuz.

Laravel ve EJB böyle bir çerçevenin örnekleridir.

Referans:

https://martinfowler.com/bliki/InversionOfControl.html

https://en.wikipedia.org/wiki/Inversion_of_control


1
Burada bulduğum en uygun cevap.
blueray

8

Konuşmayı programlama

IoC kolay terimlerle: Arabirimin, bazı sınıflar tarafından kullanılabilen joker karakter olarak belirli bir şeyin (alan veya parametre gibi) bir yolu olarak kullanılmasıdır. Kodun yeniden kullanılabilirliğine izin verir.

Örneğin, iki sınıfımız olduğunu varsayalım: Köpek ve Kedi . Her ikisi de aynı nitelikleri / durumları paylaşır: yaş, boyut, ağırlık. Bu nedenle, DogService ve CatService adlı bir hizmet sınıfı oluşturmak yerine, Dog ve Cat'i yalnızca IAnimal arayüzünü kullanıyorlarsa kullanmanıza izin veren AnimalService adlı tek bir tane oluşturabilirim .

Bununla birlikte, pragmatik olarak konuşursak, biraz geriye doğru vardır.

a) Geliştiricilerin çoğu onu nasıl kullanacaklarını bilmiyorlar . Örneğin, Müşteri adlı bir sınıf oluşturabilirim ve ICustomer adlı bir arabirimi otomatik olarak (IDE araçlarını kullanarak) oluşturabilirim . Bu nedenle, arayüzler yeniden kullanılacak veya kullanılmayacak olursa olsun, sınıflar ve arayüzlerle dolu bir klasör bulmak nadir değildir. Buna BLOATED denir. Bazı insanlar "gelecekte kullanabileceğimizi" iddia edebilirler. : - |

b) Bazı sınırlamaları vardır. Örneğin, Köpek ve Kedi hakkında konuşalım ve ben sadece köpekler için yeni bir hizmet (işlevsellik) eklemek istiyorum. Diyelim ki bir köpeği eğitmem gereken gün sayısını hesaplamak istiyorum ( trainDays()), kedi için işe yaramaz, kediler eğitilemez (şaka yapıyorum).

b.1) trainDays()Hizmet AnimalService'e eklersem, o zaman kedilerle de çalışır ve hiç geçerli değildir.

b.2) trainDays()Hangi sınıfın kullanıldığını değerlendirdiği yere bir koşul ekleyebilirim . Ancak IoC'yi tamamen kıracak.

b.3) Sadece yeni işlevler için DogService adlı yeni bir hizmet sınıfı oluşturabilirim . Ancak, kodun sürdürülebilirliğini artıracaktır, çünkü Dog için iki hizmet sınıfına (benzer işlevlerle) sahip olacağız ve kötü.


Şişirilmiş sınıflar / arabirimler hakkında: Her bir arabirimi her zaman yeniden kullanmanız gerekmez. Bazen büyük bir arayüzü işlevsel sınırlarını görmek için çok daha küçük boyutlara bölmek mantıklıdır. Daha küçük arayüzlerin diğer uygulamalarda tekrar kullanılması daha kolaydır. Ayrıca, mantıklı olduğu her yerde bir arayüze kod yazmanızı da teşvik eder. "Arayüz Ayrımı" nı düşünün. Sadece bir arayüz kullandığınız için, birbirinden ayrıldığınız anlamına gelmez. Tek bir yağ arayüzü işe yaramaz. - Sadece 2 sentim :)
MK

7

Bunun için birçok cevap okudum ama eğer birisi hala kafası karışmışsa ve IoC'yi açıklamak için bir artı "layman terimi" gerekiyorsa, burada benim almam:

Bir ebeveyn ve çocuğun birbirleriyle konuştuğunu düşünün.

IoC olmadan:

* Veli : Yalnızca size soru sorduğumda konuşabilir ve yalnızca size izin verdiğimde hareket edebilirsiniz.

Ebeveyn : Bu, size sormazsam yiyebilir, oynayabilir, banyoya gidip uyuyabileceğinizi soramazsınız demektir.

Ebeveyn : Yemek yemek ister misin?

Çocuk : Hayır.

Ebeveyn : Tamam, geri döneceğim. Beni bekle.

Çocuk : (Oynamak istiyor ama ebeveynin sorusu olmadığı için çocuk hiçbir şey yapamıyor).

1 saat sonra...

Ebeveyn : Geri döndüm. Oynamak ister misin?

Çocuk : Evet.

Ebeveyn : İzin verildi.

Çocuk : (sonunda oynayabilir).

Bu basit senaryo, denetimin ana öğeye ortalandığını açıklar. Çocuğun özgürlüğü sınırlıdır ve büyük ölçüde ebeveynin sorusuna bağlıdır. Çocuk SADECE konuşması istendiğinde konuşabilir ve SADECE izin verildiğinde hareket edebilir .

IoC ile:

Çocuk şimdi soru sorma yeteneğine sahiptir ve ebeveyn cevaplar ve izinlerle yanıt verebilir. Kontrolün ters çevrildiği anlamına gelir! Çocuk artık istediği zaman soru sormakta serbesttir ve izinler konusunda ebeveynine hala bağımlılık olsa da, konuşma / soru sorma araçlarına bağımlı değildir.

Teknolojik bir şekilde, bu GUI etkileşimi ile konsol / kabuk / cmd'ye çok benzer. (Mark Harrison, 2 numaralı cevabın üstünde). Konsolda, size sorulan / görüntülenen şeylere bağımlısınız ve önce sorusunu cevaplamadan diğer menülere ve özelliklere atlayamazsınız; sıkı bir ardışık akışı takiben. (programlı olarak bu bir yöntem / fonksiyon döngüsü gibidir). Bununla birlikte, GUI ile menüler ve özellikler düzenlenir ve kullanıcı ihtiyaç duyduğu her şeyi seçebilir, böylece daha fazla kontrole ve daha az kısıtlamaya sahip olabilir. (programlı olarak, menüler seçildiğinde geri aramaya sahiptir ve bir eylem gerçekleşir).


6

Kontrolün ters çevrilmesi, kontrolün kütüphaneden istemciye aktarılması ile ilgilidir. Bir istemciden, bir işlev değerini (lambda ifadesi), kütüphane işlevinin davranışını denetleyen (değiştiren) daha yüksek bir düzeye (kütüphane işlevi) enjekte eden (geçiren) hakkında daha anlamlı olur. Kütüphane bağımlılıklarını (davranış taşıyan) kütüphanelere enjekte eden bir istemci veya çerçeve de IoC olarak düşünülebilir


5

Zaten soru için birçok cevap var, ancak hiçbiri Tersine Çevirme teriminin dökümünü göstermediğinden, daha özlü ve kullanışlı bir cevap verme fırsatı görüyorum.

Kontrolün Tersine Çevirilmesi, Bağımlılık Ters Çevirme İlkesini (DIP) uygulayan bir modeldir. DIP aşağıdakileri belirtir: 1. Yüksek seviye modülleri, düşük seviye modüllerine bağlı olmamalıdır. Her ikisi de soyutlamalara (örn. Arayüzler) bağlı olmalıdır. 2. Soyutlamalar detaylara bağlı olmamalıdır. Ayrıntılar (somut uygulamalar) soyutlamalara bağlı olmalıdır.

Üç tür Kontrol Tersine Çevirme vardır:

Arabirim Ters Çevirme Sağlayıcıları bir arabirim tanımlamamalıdır. Bunun yerine, tüketici arayüzü tanımlamalı ve sağlayıcılar bunu uygulamalıdır. Arabirim Ters Çevirme, yeni bir sağlayıcı eklendiğinde her seferinde tüketiciyi değiştirme gereğini ortadan kaldırır.

Akış Ters Çevirme kontrolünü değiştirir. Örneğin, birçok parametre girmenizi istediğiniz bir konsol uygulamanız var ve girilen her parametreden sonra Enter tuşuna basmanız gerekiyor. Flow Inversion'ı buraya uygulayabilir ve kullanıcının parametre girme sırasını seçebileceği, kullanıcının parametreleri düzenleyebileceği ve son adımda kullanıcının Enter tuşuna yalnızca bir kez basması gereken bir masaüstü uygulaması uygulayabilirsiniz.

Yaratılış İnversiyonu Aşağıdaki şablonlarla uygulanabilir: Fabrika Deseni, Servis Bulucu ve Bağımlılık Enjeksiyonu. Oluşturma Ters Çevirme, bağımlılık nesneleri oluşturma işlemini bu bağımlılık nesnelerini kullanan türün dışına taşıyan türler arasındaki bağımlılıkları ortadan kaldırmaya yardımcı olur. Bağımlılıklar neden kötü? Birkaç örnek: kodunuzda yeni bir nesnenin doğrudan oluşturulması, testi zorlaştırır; yeniden derleme yapmadan meclislerdeki referansları değiştirmek imkansızdır (OCP prensibi ihlali); masaüstü kullanıcı arayüzünü web kullanıcı arayüzüyle kolayca değiştiremezsiniz.


3
  1. Yani yukarıdaki 1 numara . Kontrolün Ters Çevrilmesi Nedir?

  2. Bakım benim için çözdüğü bir numaralı şey. İki sınıfın birbiriyle samimi olmaması için arayüzler kullandığımı garanti eder.

Windsor Kalesi gibi bir konteyneri kullanırken bakım sorunlarını daha da iyi çözüyor. Bir kod satırını değiştirmeden dosya tabanlı kalıcılık kullanan bir veritabanına giden bir bileşeni değiştirebilmek harika (yapılandırma değişikliği, işiniz bitti).

Ve bir kez jeneriklere girdiğinizde, daha da iyi olur. Kayıtları alan ve mesaj yayınlayan bir yayıncıya sahip olduğunuzu düşünün. Ne yayınladığı umurunda değil, ancak bir kayıttan bir mesaja bir şey almak için bir haritacıya ihtiyacı var.

public class MessagePublisher<RECORD,MESSAGE>
{
    public MessagePublisher(IMapper<RECORD,MESSAGE> mapper,IRemoteEndpoint endPointToSendTo)
    {
      //setup
    }
}

Bir kez yazdım, ancak şimdi farklı türde mesajlar yayınlarsam bu kod kümesine birçok tür enjekte edebilirim. Aynı türden bir kayıt tutan ve farklı mesajlarla eşleştiren eşleştiriciler de yazabilirim. Generics ile DI'yi kullanmak bana birçok görevi yerine getirmek için çok az kod yazma yeteneği verdi.

Ah evet, test edilebilirlik endişeleri var, ancak IoC / DI'nin faydalarına ikinciller.

Kesinlikle IoC / DI'yi seviyorum.

3. Biraz daha karmaşık orta ölçekli bir projeye sahip olduğunuz anda daha uygun hale gelir. Acı hissetmeye başlar başlamaz bunun uygun olduğunu söyleyebilirim.



3

Sınıf içinde bir nesne oluşturmaya sıkı bağlantı denir, Spring bu bağımlılığı bir tasarım deseni (DI / IOC) izleyerek ortadan kaldırır. Hangi sınıf nesnesinin sınıfta yaratmaktan ziyade kurucuya geçtiği. Daha genel yapıyı tanımlamak için yapıcıda süper sınıf referans değişkeni veriyoruz.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.