Neden Kontrolün Tersine Çevirilmesi bu şekilde adlandırılıyor?


98

Kelimeler invertya controlda hiç kullanmadığımı tanımlarda Kontrol Tersini Tanımlamak için kullanılmıyor.

Tanımlar

Vikipedi

kontrolün ters çevrilmesi (IoC) burada nesne birleştirmenin bir montajcı nesne tarafından çalışma zamanında bağlandığı ve tipik olarak statik analiz kullanılarak derleme zamanında bilinmediği, nesne yönelimli programlama anlamında ifade edilen bir programlama tekniğidir. ~ http://en.wikipedia.org/wiki/Inversion_of_control

Martin Fowler

Denetimin Tersine çevrilmesi, Java topluluğundaki hafif kapları birleştirmeye veya farklı projelerdeki bileşenleri birleştirerek birleştirici bir uygulamaya bağlayan ortak bir kalıptır. ~ http://www.martinfowler.com/articles/injection.html (yeniden düzenlendi) dayalı


Öyleyse neden Denetimin Tersine çevrilmesi Denetimin Tersine Dönmesi olarak adlandırılıyor? Hangi kontrol ters çevriliyor ve neye göre? Terminolojiyi kullanarak Kontrol İnversiyonunu tanımlamanın bir yolu var mı: invert ve kontrol ?


22
Bunu açık bir şekilde İngilizce
Robert Harvey,

2
Eğer bir tanım tanımladığı kelimeyi kullandıysa, bu bir sözlüğün başarısızlığı olurdu. Benzer mantık burada da geçerlidir.
Izkata

2
Ayrıca bakınız StackOverflow: Kontrolün Ters
Izkata

2
@Izkata, sözlüklerin cümleleri kendi cümleleriyle veya eşanlamlı terimleriyle tanımlamaları çok yaygındır. yani: doğa tanımının gücü tanımında güç ve doğa kelimelerini veya hizmet tanımı terimlerini, kuralların terimler ile eşanlamlı olduğu kurallar ve hizmet kelimelerini kullanır.
Korey Hinton

3
Bu nedenle IoC yerine "otomatik bağımlılık enjeksiyonu" veya ADI terimlerini kullanmayı tercih ediyorum; Fowler, programlamadaki mevcut paradigmaların çoğunun bir çeşit "kontrolün tersine çevrilmesi" olduğunu, bu terimin genellikle "yürütülecek kodun tespitlerinin yeniden yapılandırılması ve harici olarak yapılması gereken zaman" olarak tanımlandığından bahseder. kontrol sistemi, bu tespitler geleneksel olarak programın kendisi tarafından yapıldığında ". Donanımdan olay odaklı programlamaya ve sanal makinelere kadar her şey kesintiye uğrar ve çok görevli IoC ile gerçekleşir.
KeithS

Yanıtlar:


67

Bir çeşit "depo" sınıfı olduğunu ve bu veri kaynağının size veri iletilmesinden sorumlu olduğunu varsayalım.

Havuz, veri kaynağına kendi başına bir bağlantı kurabilir. Ancak, veri kaynağına bir veri tabanının kurucusu aracılığıyla bağlantı kurmanıza izin verirse ne olur?

Arayanın bağlantıyı sağlamasına izin vererek, veri kaynağı bağlantısının bağımlılığını depo sınıfından ayırdınız, herhangi bir veri kaynağının yalnızca havuzun belirttiği şeyi değil depo ile çalışmasına izin verdiniz .

Sen var kontrolünü ters arayana depo sınıftan bir bağlantı oluşturarak sorumluluğunu teslim ederek.

Martin Fowler, “Bağımlılık Enjeksiyonu” terimini bu tür bir İnversiyon Türünü tanımlamak için kullanmayı önerir, çünkü bir kavram olarak Kontrol İnversiyonu, bir yapıcı yöntemde bağımlılıkları enjekte etmekten daha geniş bir şekilde uygulanabilir.


3
Bu bir bağımlılık enjeksiyonunun bir örneğidir, ancak bağımlılık enjeksiyonu sadece kontrolün inversiyon alt kümesidir. Tamamen bağımlılık enjeksiyonuyla, kontrolün tersine çevrilmesini uygulayan diğer hususlar vardır.
dsw88

1
@ mustang2009cobra: Teşekkürler. Bir örnek, peşinde olduğum şeydi, gerçekleştiği kapsamlı bir örnek kataloğu değil ve "Kontrolün Tersine Çevirilmesi" terimi, mesaj iletimi veya benzeri kavramlarla değil, DI ile en yakından ilişkilidir.
Robert Harvey

Doğru, bağımlılık enjeksiyonu IoC'nin en yaygın örneğidir, bu nedenle bir DI örneği en anlamlı olanıdır. Belki de cevabınızda, bunun en belirgin IoC türü olan bir DI örneği olduğunu belirten küçük bir değişiklik olabilir?
dsw88

1
Bu tam olarak aradığım şeydi! IoC'nin birçok örneği ve tanımı, hangi kontrolün ters çevrildiğini açıkça belirtmiyor. Sadece bağımlılık enjeksiyonundan daha fazla IoC olabileceğini biliyorum ama şimdi beynimde bir şey tıkadı. Teşekkürler!
Korey Hinton

79

Bağlandığın makalenin ilerisinde , kimsenin Martin Fowler’tan daha iyi açıklayabileceğini sanmıyorum .

Bu yeni konteyner cinsi için inversiyon, bir eklenti uygulamasının nasıl göründüğü ile ilgilidir. Naif örneğime göre, lister bulucuya uygulanmasını doğrudan başlattı. Bu, bulucunun bir eklenti olmasını engeller. Bu kapların kullandığı yaklaşım, bir eklentinin herhangi bir kullanıcısının, ayrı bir montaj modülünün uygulamayı lister içine enjekte etmesine izin veren bazı kuralları takip etmesini sağlamaktır.

Yukarıdaki paragraflarda açıkladığı gibi, bu "Kontrolün Tersine Çevirilmesi" teriminin ortaya çıkma sebebi ile aynı değildir.

Bu konteynırlar bu kadar faydalı olduklarından bahsettiklerinde “Denetimin Tersini Çevirme” yi uyguladıkları için çok şaşırdım. Kontrolün tersine çevrilmesi, çerçevelerin ortak bir özelliğidir, bu nedenle bu hafif konteynerlerin özel olduğunu söylemek, kontrolün tersini kullanmaları demek, arabamın tekerlekleri olduğu için özel olduğunu söylemek gibidir.

Soru, kontrolün hangi yönünü tersine çeviriyorlar? Kontrolün ilk tersine çevrildiğinde, bir kullanıcı arayüzünün ana kontrolüydü. Erken kullanıcı arayüzleri uygulama programı tarafından kontrol edildi. "Enter name", "address girin" gibi bir dizi komutunuz olurdu; programınız istemleri yönlendirir ve her birine bir yanıt alır. Grafiksel (veya hatta ekran tabanlı) kullanıcı arayüzleri kullanıcı arayüzü çerçevesi bu ana çevrimi içerecek ve programınız bunun yerine ekrandaki çeşitli alanlar için olay işleyicileri sağlayacaktır. Programın ana kontrolü ters çevrildi, sizden çerçeveye taşındı.

Bu yüzden Kontrolün Bu Özel İnversiyon uygulamasını kapsayan “Bağımlılık Enjeksiyonu” terimini kullanmaya devam ediyor.

Sonuç olarak, bu kalıp için daha spesifik bir isme ihtiyacımız olduğunu düşünüyorum. Kontrolün Tersine çevrilmesi çok genel bir terimdir ve dolayısıyla insanlar bunu kafa karıştırıcı bulmaktadır. Çeşitli IoC savunucuları ile yapılan çok fazla tartışma sonucunda, Bağımlılık Enjeksiyonu adını verdik.

Biraz netleştirmek için: Kontrolün Tersine çevrilmesi, bir programın kontrol yapısını klasik prosedür tasarımından tersine çeviren herhangi bir şey anlamına gelir.

Eski günlerde, bunun temel bir örneği, bir UI ile kodunuz arasındaki iletişimi doğrudan UI oluşturmak için kodunuzu bırakmak yerine, bir çerçevenin yönetmesine izin vermekti.

Daha yakın zamanlarda (bu çerçeveler oldukça baskın olduğu zaman, bu yüzden soru artık alakalı değildi), bir örnek nesnelerin somutlaştırılması üzerindeki kontrolünü tersine çeviriyordu.

Fowler ve diğerleri, Inversion of Control teriminin çok fazla teknik içerdiğine karar vermiştir ve nesnelerin somutlaştırılması örneği için yeni bir terime ihtiyaç duyduğumuza karar vermiştir (Bağımlılık Enjeksiyonu), ancak anlaşma yapıldığı sırada "IoC Container" ifadesi "ayrıldı.

Bu, suyu çok fazla çamurlaştırır, çünkü bir IoC konteyneri belirli bir Bağımlılık Enjeksiyonu türüdür, ancak Bağımlılık Enjeksiyonu belirli bir Kontrol İnversiyonu türüdür. Bu yüzden nereye bakarsanız bakın, çok karışık cevaplar alıyorsunuz.


4
Normalde o kadar fazla oy kullanmam ama bu harika bir cevap. 1 oy yeterli olmaz. :(
RJD22

1
Bu cevap gerçekten tüm IoC ve DI kafa karışıklıkları sorununa cevap veriyor.
Ali Umair

32

İşte "düzenli" kontrol akışı programları genellikle takip edilir:

  • Komutları sırayla çalıştırın
  • Programın kontrol akışı üzerinde kontrol sizde

Kontrolün Tersine çevrilmesi, kontrol akışını “tersine çevirir”, yani kafasını çevirir.

  • Programınız artık akışı kontrol etmiyor. Uygun gördüğünüz komutları çağırmak yerine başkasının sizi aramasını beklersiniz .

Bu son satır önemli olan. Hoşunuza gittiğinde başkasını aramak yerine, hoşlandığı zaman başkası sizi arar.

Bunun yaygın bir örneği, Rails gibi web çerçeveleridir. Denetleyicileri tanımlarsınız, ancak ne zaman aranacaklarına siz karar veremezsiniz. Rails ihtiyaç olduğuna karar verdiğinde onları çağırır.


19
[zorunlu "Sovyette" şakasını buraya ekleyin]
Robert Harvey,

2
Şaka yapıyorum, tanımladığınızı düşündüğüm şey daha çok mesaj geçen ve yıllarca OO'nun temelini oluşturan mesaj geçişi gibi.
Robert Harvey,

3
@JimmyHoffa - Bu hiç de yanlış değil - buraya bakın . Kontrolün tersine çevrilmesi bağımlılıklar yaratmaktan daha genel bir kavramdır ve bağımlılık enjeksiyonu sadece bir IoC şeklidir.
Lee,

7
@ JimmyHoffa: Ben katılmıyorum. Bu, Yanıtınız ya da Robert'in, tam olarak tersine çevrilmesi gibi, Kontrol Bağımlılığı Enjeksiyonu (yani, her ikiniz de IoC dediğiniz şeydir) ifadesini yazarken, kargaşanın tam bir kargaşası olan Kontrolün Tersine Çevirme tanımıdır.
pdr

5
Bu ifadeye pdr ile katılıyorum: "Denetimin Tersine Çevirilmesi, bir programın denetim yapısını klasik prosedür tasarımından tersine çeviren herhangi bir şey anlamına gelir." Bunu tarif ediyorum ve bu genel kontrol çevrimidir. Bağımlılık enjeksiyonu bir tür
IoC'dir

13

Bağımlılıkların somutlaştırılmasını kimin kontrol ettiği ile ilgilidir.

Geleneksel olarak, bir sınıf / yöntem başka bir sınıf kullanmaya ihtiyaç duyduğunda (bağımlılık) doğrudan sınıf / yöntem tarafından başlatılır. Bağımlılıklarını kontrol eder.

Kontrolün Ters Çevirilmesi (IoC) ile, arayanlar bağımlılığa geçti, bu nedenle bağımlılığı başlattı. Arayan bağımlılıkları kontrol eder.

Bir bağımlılığın somutlaştırıldığı yerin kontrolü tersine çevrildi - ihtiyaç duyulan kodun olduğu “alt” olmak yerine, ihtiyaç duyduğu kodun çağrıldığı “üst” konumunda somutlaştırıldı.


1
Düz İngilizce değil. Başarısız.
Robert Harvey,

2
@RobertHarvey - düz ne kadar düz?
Oded

4
@RobertHarvey Huh? Bu bana oldukça sade görünüyor ... Ne düz değil? "Örnekleme" veya "bağımlılıklar" kelimesi?
Jimmy Hoffa,

@JimmyHoffa: Belirli bir örnek sağlayan cevabımı görün. IoC, herkesin kullandığı ve hiç kimsenin açıklamadığı sıkıntılı terimlerden biridir; İnsanlar kendileri için gerekli olmayan programlarda IoC kaplarını kullanıyor, çünkü yanlış anlıyorlar. Bununla birlikte, bu cevabın birkaç ninja düzenlemesi olduğunu düşünüyorum. :)
Robert Harvey,

Bu ve yukarıda @ dsw88 olmak benim için oldukça açık. Bakın, IoC'yi hiç duymamış olsaydım, sezgisel bir şekilde "Ah, bir şeyi kontrol altına alanın bir taraftan diğer tarafa kaçtığını" düşünürdüm. Bu işte iyi iş!
Oliver Williams

2

Tipik olarak daha yüksek seviyeli kod (yani kontroller) daha düşük seviyeli kodu çağırır. Main () function () işlevini çağırır, function () libraryFunction () işlevini çağırır.

Bu tersine çevrilebilir, bu nedenle alt kısımdaki düşük seviyeli kütüphane işlevi daha üst seviye işlevleri çağırır.

Neden bunu yapasın? Ara Katman. Bazen üst seviyeyi ve alt seviyeyi kontrol etmek istersiniz, ancak ortada sadece yapmak istemediğiniz bir sürü iş vardır. C stdlib'deki quicksort uygulamasını kullanın . Quicksort'u en üst seviyede ararsınız. Qsort (), istediğiniz gibi bir karşılaştırıcı uygulayan kendi fonksiyonunuza bir fonksiyon göstergesini verirsiniz. Qsort () çağrıldığında, bu karşılaştırıcı işlevi çağırır. qsort (), üst düzey fonksiyonunuzu kontrol ediyor / çağırıyor / kullanıyor.


1

İşte basit bir bakış:

  1. Kontrol, programın sonra ne yapacağını belirtir
  2. En üst seviyede, kontrolü kontrol eden tipik olarak iki şey vardır: uygulamanın kendisi ve kullanıcı

Eski günlerde kontrol ilk önce uygulamaya, ikinci de kullanıcıya aitti. Uygulama kullanıcıdan bir şeye ihtiyaç duyuyorsa, durur ve sorar ve bir sonraki görevine geçer. Kullanıcı etkileşimi, daha sonra ne yapacağını kontrol etmek yerine çoğunlukla veri sağlamıştır. Bu tür davranışlar bugünlerde bizim için biraz yabancı, çünkü bu tür davranışları çok sık görmüyoruz.

Bunu değiştirir ve kullanıcıya birincil kontrolü verirsek, kontrolü tersine çeviririz. Bu, uygulamanın yapması gereken bir şeyi yapmasını bekleyen kullanıcının yerine, uygulamanın yapacağı bir şeyi yapmasını bekleyen kullanıcının oturduğu anlamına gelir. GUI buna harika bir örnektir ve bir olay döngüsüne sahip herhangi bir şey kontrolü tersine çevirmiştir.

Örneğimin en üst seviyede olduğunu ve bu kontrolün tersine çevrilmesi kavramının uygulama içindeki farklı kontrol katmanlarına (örn. Bağımlılık enjeksiyonu) soyutlanabileceğini unutmayın. Bu yüzden doğru bir cevap almak bu kadar zor olabilir.


0

İki örnekle anlamaya çalışalım.

örnek 1

Daha önceki günlerde, komut üretmek için kullanılan uygulamalar, kullanıcı girişlerini birbiri ardına kabul etmek ister. Bugün, UI çerçeveleri çeşitli UI öğelerini başlatır, bu UI öğelerinin çeşitli olaylarını (fare vurgusu, tıklama vb.) Geçirir ve kullanıcı / ana programlar bu olayları dinlemek için kancalar (örneğin, Java'daki UI olay dinleyicileri) sağlar. Böylece, ana UI eleman akışı "kontrol", kullanıcı programından UI çerçevesine taşınır. Daha önceki günlerde, kullanıcı programındaydı.

Örnek 2

CustomerProcessorAşağıdaki sınıfı düşünün :

class CustomerProcessor
{
    SqlCustRepo custRepo = new SqlCustRepo(); 
    private void processCustomers()
    {
            Customers[] custs = custRepo.getAllCusts();
    }
}

Eğer sadece sağladığım processCustomer()herhangi bir uygulamadan bağımsız olmak istersem , hattan kurtulmam gerekecek ve onu daha genel bir şeyle değiştirmeliyim, çeşitli uygulama türlerini kabul edebilecek, bunun için sadece çalışacak sağlanan herhangi bir uygulama. Yukarıdaki kod ( ana program mantığına göre zorunlu sınıfın somutlaştırılması ) geleneksel bir yöntemdir ve uygulamasından ayrılma amacına ulaşmamaktadır . Kontrolün tersine, kap, istenen uygulama sınıfını başlatır (xml konfigürasyonu ile belirtildiği gibi), onu belirtilen kancalara göre bağlanan ana program mantığına enjekte eder (örneğin , yay çerçevesindeki açıklama veya yöntemle).getAllCusts()SqlCustRepoSqlCustRepo custRepo = new SqlCustRepo()processCustomers()SqlCustRepoprocessCustomers()getAllCusts()@AutowiredgetBean()

Bunun nasıl yapılabileceğini görelim. Aşağıdaki kodu düşünün.

config.xml

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
    <bean id="custRepo" class="JsonCustRepo" />
</beans>

CustRepo.java

interface ICustRepo 
{ ... }

JsonCustRepo.java

class JsonCustRepo implements CustRepo
{ ... }

App.java

class App
{
    public static void main(String[] args) 
    {
        ApplicationContext context = new ClassPathXmlApplicationContext("Config.xml");
        ICustRepo custRepo = (JsonCustRepo) context.getBean("custRepo");
    }
}

Biz de olabilir

class GraphCustRepo implements ICustRepo { ... }   

ve

<bean id="custRepo" class="GraphCustRepo">

ve App.java'yı değiştirmemize gerek kalmayacak.

Kabın üstünde (yay çerçevesi olan) xml dosyasını tarama, belirli tipteki fasulyeyi örnekleme ve kullanıcı programına enjekte etme sorumluluğu vardır. Kullanıcı programının hangi sınıfın başlatıldığının kontrolü yok.

Not: IoC genel bir kavramdır ve birçok yönden elde edilir. Yukarıdaki örneklere bağımlılık enjeksiyonuyla ulaşılmaktadır.

Kaynak: Martin Fowler'in makalesi .

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.