Kontrolün İnversiyonu (IoC) ilk karşılaşıldığında oldukça kafa karıştırıcı olabilir.
- Bu ne?
- Hangi sorunu çözüyor?
- Ne zaman kullanılmalı, ne zaman kullanılmamalıdır?
Kontrolün İnversiyonu (IoC) ilk karşılaşıldığında oldukça kafa karıştırıcı olabilir.
Yanıtlar:
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, TextEditor
ile 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 TextEditor
sınıf doğrudan sınıfa bağlıdır SpellChecker
.
İkinci kod örneğinde, SpellChecker
bağımlılık sınıfını TextEditor
yapı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 TextEditor
sınıfı oluşturan istemci SpellChecker
, TextEditor
imzaya bağımlılığı enjekte ettiğimiz için hangi uygulamanın kullanılacağını denetliyor .
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.
Kontrolün Ters Çevrilmesi Nedir?
Bu basit iki adımı izlerseniz, kontrolü tersine çevirdiniz:
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
what-to-do
vewhen-to-do
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.
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).
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ı:
Eksileri:
Ş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).
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.
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.
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.
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.
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.
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.
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.
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.
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.
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 .
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
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 .
Ö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 .
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:-
"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?
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.
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.
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:
Bağımlılık enjeksiyonunu kullanma
DI kullanan bir kod kabaca şu şekilde çalışacaktır:
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 new
anahtar 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, new
GoogleDriveService 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.
Ç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. "
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
IoC, kodunuz ile üçüncü taraf kodu (kütüphane / çerçeve) arasındaki ilişkiyi tersine çevirmekle ilgilidir:
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 :)
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.
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.
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:
...
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:
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ü.
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).
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
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.
Yani yukarıdaki 1 numara . Kontrolün Ters Çevrilmesi Nedir?
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.
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.