Bağımlılık enjeksiyonuna özel olarak tasarlanmış bir programlama dili var mı?


21

Birçok genel programlama dili, bağımlılık enjeksiyonunu desteklemenize izin verecek kadar esnektir. Kütüphane veya çerçeve desteği olmadan bile. Ancak bir dil, herhangi bir programlama problemini çözmek için yeterince eksiksiz olsa bile, bir dil, neyin kolay ve neyin zor olduğunu belirleyen seçimler yapar.

Bağımlılık enjeksiyonunu kolaylaştırmak ve özel olarak gizli bağımlılıklar yaratmayı zorlaştırmak için özel olarak tasarlanmış herhangi bir dil var mı?

Açıklama:

Bazı dillerin sınırlamaları nedeniyle (size Java'ya bakarken), birçok kişi bağımlılık enjeksiyonunun bir parçası olarak kablolama ve yapım konusunda yardım görüyor. Burada sadece DI için tasarlanan bir dili, bağımlılığın yan etkilerde kolayca gizlenemediği anlamına gelir. Konfigürasyon sistemi üzerinde bir kongre olması da sadece sos ekleyecekti.

Dil önerisi aramıyorum. Bu tarihi bir soru. Herhangi bir dil yazarı açıkça bunu yapmaya karar verdi mi?


1
Kesin olarak birbiriyle ilişkili değilse, birbiriyle yakından ilişkili: Bağımlılık enjeksiyonunun dile nasıl entegre edilebilir?
Robert Harvey

Whee! 3K! Şimdi bu soruyu kapatmak için oy kullanmalarını izleyebilirim. :) Oylarınız için teşekkürler.
candied_orange

1
Yine de o yazıyı okumalısın. "Var mı", "nasıl yaptılar?" Gibi bir şeye genişletmediğiniz sürece, çok daha az ilginç bir sorudur.
Robert Harvey

1
Haskell sayılır mı? Körleme ve üst düzey işlevlerle, DI'nin genel olarak OOP dillerinde çözdüğü sorunların çoğunu çözebilirsiniz ve saflık konusundaki kesinliği ile IO vb gibi yan etkileri ayırmaya zorlanırsınız ve işlevler sihirli bir şekilde argüman olarak geçirilen bir şeyi oluşturamazlar. Konfigürasyon ile ilgili herhangi bir konvansiyon alamıyorsunuz, ancak diğer yandan bugünlerde OOP kodumdan bile yavaşça uzaklaşıyorum çünkü çoğu takımın orta ölçekli projelerde ve daha büyük projelerde buna güvenemeyeceğini fark ettim.
wasatz

1
@ wasatz: Evet, Haskell önemli. Çoğu "yazılım modeli", programlama dilindeki eksiklikler için gerçekten geçici çözümlerdir.
Robert Harvey,

Yanıtlar:


21

Evet, gerçekten var. Sırala.

Newspeak'in statik durumu ve global durumu yoktur. Bu, bir bağımlılığa erişmenin tek olası yolunun açıkça enjekte edilmek olduğu anlamına gelir. Açıkçası, bu, dilin veya Newspeak durumunda daha kesin olarak, IDE'nin bağımlılık enjeksiyonunu kolaylaştırması gerektiği anlamına gelir , aksi takdirde dil kullanılamaz olacaktır.

Dolayısıyla, dil DI için tasarlanmamıştır, bunun yerine DI'nin gerekliliği dil tasarımının bir sonucudur.

Eğer statik bir durum ve küresel bir durum yoksa, o zaman etere sadece “uzanıp” erişemez ve bir şey çıkaramazsınız. Örneğin, Java'da paket yapısı statik durumdur. Söyleyebilirim java.lang.Stringve kendime bir Stringsınıf verdim . Newspeak'te bu mümkün değil. Çalıştığınız her şey, size açıkça verilmek zorundadır, aksi taktirde alamazsınız. Yani, her şey bir bağımlılık ve her bağımlılık açıktır.

Bir dize ister misin? İlk önce stdlibnesneden sana Stringsınıfı vermesini istemek zorundasın . Oh, ama nasıl erişirsiniz stdlib? İlk önce nesneyi platformsize vermesini istemeniz gerekir stdlib. Oh, ama nasıl erişirsiniz platform? Öncelikle, platformnesneyi sana vermesini başka birinden istemelisin . Oh, peki ya dayanan birine nasıl erişirsiniz? İlk önce, başka bir kişiden size nesneyi size vermesini istemek zorundasınız.

Tavşan deliğinden ne kadar ileri gidiyor? Özyineleme nerede durur? Bunca yolu aslında. Durmuyor. O zaman Newspeak'te nasıl bir program yazabilirsiniz? Kesinlikle, kesinlikle konuşamazsın!

Hepsini birbirine bağlayan bazı dış varlıklara ihtiyacınız var. Newspeak'te bu varlık IDE'dir. IDE tüm programı görür. Ayrı parçaları birbirine bağlayabilir. Newspeak'teki standart model, uygulamanızın merkezi sınıfının adında bir erişimciye sahip olmasıdır platformve Newspeak IDE, programlamanın temel gerekliliklerinden bazılarını döndüren yöntemleri olan o erişimciye bir nesne enjekte eder: bir Stringsınıf, bir Numbersınıf, bir Arraysınıf, ve bunun gibi.

Uygulamanızı test etmek istiyorsanız platform, Fileyöntemi kukla yöntemlerle bir sınıf döndüren bir nesneyi enjekte edebilirsiniz . Uygulamanızı buluta dağıtmak istiyorsanız, Filesınıfı gerçekten Amazon S3 tarafından desteklenen bir platform enjekte ediyorsunuz . Platformlar arası GUI'ler, farklı işletim sistemleri için farklı GUI çerçeveleri enjekte ederek çalışır. Newspeak bile, farklı bir GUI uygulamasını yerel masaüstünden tarayıcıya hiçbir değişiklik yapmadan, sadece farklı GUI öğelerini enjekte ederek değiştirmenize olanak tanıyan deneysel bir Newspeak'ten ECMAScript derleyicisine ve HTML destekli GUI çerçevesine sahiptir.

Uygulamanızı dağıtmak istiyorsanız, IDE, uygulamayı diskteki bir nesneye serileştirebilir. (Atalarından farklı olarak, Smalltalk, Newspeak görüntü dışı bir nesne seri hale getirme formatına sahiptir. Tüm görüntüyü yanınızda götürmeniz gerekmez, tam olarak tüm bağımlılıklar enjekte edilir: IDE uygulamanızın sistemin hangi bölümlerini tam olarak bildiğini bilir . kullanır ve bunu yapmaz. Bu nedenle uygulamanızı oluşturan nesne alanının bağlı alt metnini seri hale getirir, başka bir şey yapmaz.)

Bunların hepsi sadece nesne yönelimini en uç noktaya taşıyarak işe yarar: her şey sanal yöntem çağrısıdır (Newspeak'in soyundan gelen Smalltalk terminolojisinde "mesaj gönder"). Süper sınıf araması bile sanal bir yöntem çağrısıdır! Gibi bir şey al

class Foo extends Bar // using Java syntax for familiarity

veya, Newspeak’te:

class Foo = Bar () () : ()

Java'da bu Foo, statik global ad alanında bir ad oluşturacak ve statik global ad alanına bakacak Barve Bar Fooüst sınıf yapacaktır . Çok daha dinamik olan Ruby'de bile, bu hala global isim alanında statik bir sabit yaratacaktır.

Newspeak'te eşdeğer bildirim şu anlama gelir: adında bir getter metodu oluşturun Foove bu metodu çağırarak üst sınıfına bakacak bir sınıfı geri getirin Bar. Not: Bu, üst sınıf bildirimi olarak herhangi bir çalıştırılabilir Ruby kodu koyabileceğiniz Ruby'ye benzemez , ancak kod yalnızca sınıf oluşturulduğunda ve bu kodun dönüş değeri sabit üst sınıf olduğunda yalnızca bir kez çalıştırılır . Hayır. Her bir yöntem araması Bariçin yöntem çağrılır !

Bunun bazı derin etkileri vardır:

  • bir karışım temelde henüz üst sınıfını bilmeyen bir sınıf olduğu için ve Newspeak'te, üst sınıf dinamik bir sanal yöntem çağrısıdır ve bu nedenle bilinmeyen her sınıf otomatik olarak bir karışımdır. Bedava miks olsun.
  • bir iç sınıf sadece bir sınıf döndüren bir yöntem çağrısı olduğundan, bu yöntemi dış sınıfın bir alt sınıfında geçersiz kılabilirsiniz, böylece her sınıf sanaldır. Ücretsiz sanal sınıflar alıyorsunuz:

    class Outer {
      class Inner { /* … */ }
    }
    
    class Sub extends Outer {
      override class Inner { /* … */ }
    }
    

    Newspeak:

    class Outer = () (
      class Inner = () () : ()
    ) : ()
    
    class Sub = Outer () (
      class Inner = () () : ()
    ) : ()
    
  • süper sınıf sadece bir sınıf döndüren bir yöntem çağrısı olduğundan, bu yöntemi dış sınıfın bir alt sınıfında geçersiz kılabilirsiniz, süper sınıfta tanımlanan iç sınıfların alt sınıfta farklı bir üst sınıfları olabilir. Sınıf hiyerarşi mirasını ücretsiz alırsınız:

    class Outer {
      class MyCoolArray extends Array { /* … */ }
    }
    
    class Sub extends Outer {
      override class Array { /* … */ }
      // Now, for instances of `Sub`, `MyCoolArray` has a different superclass 
      // than for instances of `Outer`!!!
    }
    

    Newspeak:

    class Outer = () (
      class MyCoolArray = Array () () : ()
    ) : ()
    
    class Sub = Outer () (
      class Array = () () : ()
    ) : ()
    
  • ve son olarak, bu tartışma için en önemlisi: çünkü (sınıfınızda tanımladığınızların dışında, açıkça) yalnızca sözlü olarak sınıfınızdaki sınıf (lar) ın ve üst sınıfın en üst sınıfındaki sınıfınızdaki yöntemleri çağırabilirsiniz. herhangi yöntemleri arayamam hiç açıkça enjekte edilenler dışında: üst sınıf bildirimi bir nedeni, bir üst düzey sınıf olan yöntemler de diyebiliriz kapatıcı bir sınıfı yok ve varsayılan dışında bir üst sınıfı olamaz yöntem çağrısı ve açıkçası (üst sınıf gidemez olduğunusüper sınıf) ve aynı zamanda sözcüksel sınıfa giremez, çünkü hiçbiri yoktur. Bunun anlamı, üst sınıf sınıfların tamamen kapsüllenmesi, yalnızca açıkça enjekte edildikleri şeye erişebilmeleri ve yalnızca açıkça istediklerini enjekte edilmeleridir. Başka bir deyişle: üst seviye sınıflar modüllerdir. Tüm modül sistemine ücretsiz sahip olursunuz. Aslında, daha kesin olmak gerekirse: üst düzey sınıflar modül bildirimleridir, örnekleri modüllerdir. Böylece, parametrik modül bildirimleri ve birinci sınıf modülleri ücretsiz olan bir modül sistemi elde edersiniz, çok, hatta çok karmaşık olan modül sistemlerinin yapamayacağı bir şey.

Tüm bu enjeksiyonu acısız hale getirmek için, sınıf beyanları alışılmadık bir yapıya sahiptir: bunlar iki beyandan oluşur. Biri sınıf yapıcı olduğunu değil oluşturur yapıcı örneklerini çevreyi sınıf vücut çalışır inşa sınıfın değil, yapıcı. Java benzeri bir sözdiziminde şuna benzer bir şey görünür:

class Foo(platform) extends Bar {
  Array  = platform.collections.Array
  String = platform.lang.String
  File   = platform.io.File
| // separator between class constructor and class body
  class MyArray extends Array { /* … */ }
  // Array refers to the method defined above which in turn gets it from the 
  // platform object that was passed into the class "somehow"
}

Newspeak:

class Foo using: platform = Bar (
  Array = platform collections Array
  String = platform streams String 
  File = platform files ExternalReadWriteStream
) (
  class MyArray = Array () () : ()
) : ()

Bir Newspeak programcısının sınıf (ları) gerçekten görmesinin yolunun şöyle olduğuna dikkat edin :Birden fazla iç içe sınıf görüntüleyen Newspeak IDE

Yine de adalet yapmaya başlayamam bile. Kendinle oynamak zorunda kalacaksın. Gilad Bracha, modülerlik dahil olmak üzere sistemin çeşitli yönleri hakkında birkaç konuşma yaptı . İlk saatini modülerlik hikayesi de dahil olmak üzere dilin kapsamlı bir tanıtımı olan gerçekten uzun (2 saat) bir konuşma yaptı . Newspeak Programming Platform'un 2. Bölümü modülerliği kapsamaktadır. Eğer Squeak'te Newspeak'i gözden kaçırırsanız - Çapraşıklar için bir Rehber (aka Newspeak-101) , sistem için bir fikir edinirsiniz. Örnek ile Newspeak canlı bir dökümandır (yani ECMASCript'in Newspeak-on-Port'unda çalışıyor, her kod satırı düzenlenebilir, her sonuç denetlenebilir) temel sözdizimini gösteren.

Ama gerçekten, onunla oynamak zorundasın. Sadece bir çok farklı o deneyimli olması gerekir, açıklaması zor olduğunu tüm ana akımdan ve hatta en olmayan ana akım dilleri.


3
Meh. Statik durum ve küresel durumun kullanılmasını yasaklayın ve bunu neredeyse her modern programlama dili için söyleyebilirsiniz.
Robert Harvey

Meraklı, el yapımı enjeksiyon kaplarının çoğu statik fabrikalar. Bunu daha önce kötü bir şey olarak düşünmemiştim.
candied_orange

@ Jörg Bu cevabı biraz daha yedekleyebilmenin bir yolu var mı? "Newspeaklanguage.org bağımlılık enjeksiyonunu" googledim ve boş geldi. Bulabildiğim
candied_orange

@CandiedOrange: Cevabı genişletme sürecindeydim ama sonra "gerçek dünya" engelledi. Bu daha iyi mi?
Jörg W Mittag

3
@ JörgWMittag Kutsal bok! Peki kesinlikle "daha". Ben "daha iyi" değerlendirirken bekle. Bundan kurtulmak için bir banyo ziyaretinin gücüne ihtiyaç duyabilirsiniz.
candied_orange

7

Wake Programlama dili , bağımlılık enjeksiyonunu kullanmak için tasarlanmıştır. Temel olarak, dilin içine yerleştirilmiş bir bağımlılık enjeksiyon çerçevesine eşdeğerdir. Sınıflar, kendileri needve providederleyici her şeyi bir araya getirdiği parametreleri tanımlar .


6

Pratik olarak kullanışlı bir dil değil, ancak bu yazıda anlatılan sistem ilginç bir etkiye sahiptir: soyut sınıfları / arayüzleri kullanarak soyut bir sınıf yazmanıza olanak tanır (bunları başlatmak da dahil olmak üzere) örnekleme noktasında kullandığınız her soyut sınıf. Bunu yapmak, bağımlılık enjeksiyonuna olan ihtiyacı en azından basit durumlarda ortadan kaldırır, örneğin (bu özellik ile birlikte verilen Java'nın varsayımsal bir sürümünü kullanarak) bu kodu alabiliriz:

public interface I {
    void something ();
)

public class Concrete implements I {
    public void something () { ... }
}

public class Client {
    I myI;
    public Client (I injected) { myI = injected; }
    ...
}

...

    Client c = new Client (new Concrete());
    ...

ve Müşteriyi ve kullanımını şununla değiştirin:

public class Client {
   I myI = new I();
   ...
}

   Client c = new Client { I -> Concrete } ();

Bunun, yaratımdan ziyade bir bağımlılığın kullanım noktasını basitleştirdiğine dikkat edin. Ayrıca Fabrika düzeninden de kaçınmamıza olanak tanır (yeni olarak istediğimiz zaman talep üzerine oluşturulabilir).


İlginç. Bu bana Scala'nın alt üyelerinde geçersiz kılınabilen ve bir üst sınıfta soyut bırakılan Tip Üyelerini hatırlatıyor. Öz Tip Ek Açıklamalar ile birleştirilen Soyut Tip Üyeler, Scala'nın modülerlik ve bağımlılık enjeksiyonuna yaklaşımının temelini oluşturur. Bu yazının hem Scala'nın tasarımcısı Martin Odersky , hem de Newspeak'in tasarımcısı Gilad Bracha tarafından aktarıldığına hiç şaşırmadım .
Jörg W Mittag

0

Ben kullanmadım, ancak Plastik programlama dilinin resmi tanıtım çizgisi " Bağımlılık enjeksiyonunu yapar ve bir programlama diline eklerseniz ne olur? " Oldukça ilginç görünüyor

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.