Birisi, bir yapıcı işlevi ile Javascript'teki bir fabrika işlevi arasındaki farkı açıklayabilir.
Bir diğerini ne zaman kullanmalı?
Birisi, bir yapıcı işlevi ile Javascript'teki bir fabrika işlevi arasındaki farkı açıklayabilir.
Bir diğerini ne zaman kullanmalı?
Temel fark, bir yapıcı işlevinin
new anahtar kelime (JavaScript'in otomatik olarak yeni bir nesne oluşturmasına neden olan
this Bu nesnenin işlevi içinde ve nesneyi döndürür):
var objFromConstructor = new ConstructorFunction();
Bir fabrika işlevi "normal" işlev gibi çağrılır:
var objFromFactory = factoryFunction();
Ama bunun bir "fabrika" olarak görülmesi için, bir nesnenin yeni bir örneğini döndürmesi gerekecek: bir boolean ya da bir şey döndürdüyse, buna "fabrika" işlevi diyemezsiniz. Bu, otomatik olarak gerçekleşmez
newAncak bazı durumlarda daha fazla esneklik sağlar.
Gerçekten basit bir örnekte, yukarıda atıfta bulunulan işlevler şöyle bir şeye benzeyebilir:
function ConstructorFunction() { this.someProp1 = "1"; this.someProp2 = "2"; } ConstructorFunction.prototype.someMethod = function() { /* whatever */ }; function factoryFunction() { var obj = { someProp1 : "1", someProp2 : "2", someMethod: function() { /* whatever */ } }; // other code to manipulate obj in some way here return obj; }
Elbette fabrika fonksiyonlarını bu basit örnekten daha karmaşık hale getirebilirsiniz.
Bazı insanlar fabrika işlevlerini her şey için kullanmayı tercih ediyorlar çünkü kullanmayı hatırlamaktan hoşlanmıyorlar.
new (DÜZENLE: ve bu bir sorun olabilir çünkü
new işlev hala çalışır ancak beklendiği gibi olmaz). Bunu bir avantaj olarak görmüyorum:
new dilin çekirdek bir parçasıdır, bu yüzden benim için kasıtlı olarak kaçınmak biraz keyfi - diğer anahtar kelimeler gibi kaçınmak gibi
else.
Fabrika işlevlerinin bir avantajı, döndürülecek nesnenin bazı parametrelere bağlı olarak birkaç farklı türde olması olabilir.
Çoğu kitap, kurucuları kullanmanızı ve
new
this yeni nesneyi ifade eder
Bazı insanlar yolu sever
var myFoo = new Foo(); okur.
Aramanın ayrıntıları çağrı API'sine sızdı (
new gereksinim), bu nedenle tüm arayanlar yapıcı uygulamasına sıkı sıkıya bağlıdır. Fabrikanın ek esnekliğine ihtiyacınız olursa, tüm arayanları (kuraldan ziyade istisnai durum) kabul etmelisiniz.
unutma
new Böyle yaygın bir hatadır, kurucunun doğru bir şekilde çağrıldığından emin olmak için bir kazan denetimi eklemeyi kesinlikle düşünmelisiniz (
if (!(this instanceof Foo)) { return new Foo() } ). DÜZENLEME: ES6'dan beri (ES2015) unutamazsınız
new Birlikte
class kurucu veya kurucu bir hata atacaktır.
Yaparsan
instanceof kontrol edin, belirsiz olup olmadığını belirsizliğe bırakır
new gerekli. Benim düşüncemde olmamalı. Etkili olarak kısa devre yaptınız
new gereksinimi, yani # 1 dezavantajını silebilirsiniz. Ama sonra Sadece isminde bir fabrika işlevine sahipsinek boilerplate, büyük harf ve daha az esnek
this bağlamı.
Ama benim asıl kaygım, açık / kapalı ilkeyi ihlal etmesi. Bir kurucuyu dışa aktarmaya başlarsınız, kullanıcılar kurucuyu kullanmaya başlarlar, daha sonra bir fabrikanın esnekliğine ihtiyaç duyduğunuzu fark ettiğiniz yoldan aşağıya inersiniz (örneğin, uygulamayı nesne havuzlarını kullanmak için değiştirmek veya yürütme bağlamları arasında örnek oluşturmak için) prototip OO kullanarak daha fazla kalıtım esnekliği var.
Yine de sıkışmışsın. Yapıcınızı çağıran tüm kodu kırmadan değişikliği yapamazsınız.
new. Örneğin, performans artışı için nesne havuzlarını kullanmaya başlayamazsınız.
Ayrıca, kurucuları kullanarak bir aldatmaca verir
instanceof Bu, yürütme bağlamlarında çalışmaz ve kurucunuzun prototipi değiştirilirse çalışmaz. Geri dönmeye başlarsanız başarısız olur
this kurucunuzdan ve sonra yapıcınızdaki fabrika benzeri davranışı etkinleştirmek için yapmanız gereken keyfi bir nesneyi dışa aktarmaya geçin.
Daha az kod - boilerplate gerekli.
Herhangi bir rastgele nesneyi döndürebilir ve herhangi bir keyfi prototip kullanabilir ve aynı API'yi uygulayan çeşitli nesneler oluşturmak için size daha fazla esneklik kazandırabilirsiniz. Örneğin, hem HTML5 hem de flash oynatıcıların örneklerini oluşturabilen bir medya oynatıcı veya DOM olaylarını veya web soket olaylarını yayabilecek bir etkinlik kütüphanesi. Fabrikalar, aynı zamanda, uygulama bağlamları boyunca nesneleri başlatabilir, nesne havuzlarından yararlanabilir ve daha esnek prototipli kalıtım modellerine olanak tanır.
Bir fabrikadan kurgana dönüşme gereği duymazsınız, bu nedenle yeniden düzenleme hiçbir zaman bir sorun olmayacaktır.
Kullanım hakkında hiçbir belirsizlik
new. Yapma. (Yapacak
this kötü davranmak, sonraki noktaya bakınız).
this normalde olduğu gibi davranır - böylece ana nesneye erişmek için kullanabilirsiniz (örneğin,
player.create(),
this ifade eder
playerTıpkı başka herhangi bir yöntem çağrısı gibi.
call ve
apply ayrıca atayın
this, beklenildiği gibi. Prototipleri ana nesnede depolarsanız, bu işlevler dinamik olarak takas etmenin ve nesne eşleştirmeniz için çok esnek bir polimorfizme olanak tanımanın harika bir yolu olabilir.
Büyük harf kullanıp kullanmama konusunda bir belirsizlik yok. Yapma. Lint araçları şikayet edecek ve sonra kullanmayı denemek için cazip olacaksınız
newve sonra yukarıda açıklanan faydayı geri alırsınız.
Bazı insanlar yolu sever
var myFoo = foo(); veya
var myFoo = foo.create(); okur.
new beklenildiği gibi davranmaz (yukarıya bakın). Çözüm: kullanma.
this yeni nesneye başvurmaz (eğer yapıcı nokta notasyonu veya köşeli ayraç notasyonu ile çağrılırsa, ör. foo.bar () -
this ifade eder
foo - Diğer tüm JavaScript metotları gibi - faydaları gör).
Bir kurucu, onu çağırdığınız sınıfın bir örneğini döndürür. Bir fabrika işlevi herhangi bir şey döndürebilir. Rasgele değerler döndürmeniz gerektiğinde veya bir sınıfın büyük bir kurulum süreci olduğunda bir fabrika işlevini kullanırsınız.
Fabrikalar "her zaman" daha iyidir. Nesne yönelimli dilleri kullanırken o zaman
Uygulamalar (yeni ile oluşturulan gerçek nesneler) fabrika kullanıcısına / tüketicisine maruz kalmaz. Bu, fabrika geliştiricisinin sözleşmeyi bozmadığı sürece yeni uygulamalar geliştirip geliştirebileceği anlamına gelir ... ve fabrika tüketicisinin kodlarını değiştirmek zorunda kalmadan yeni API'den faydalanmasını sağlar ... Yeni ve "yeni" bir uygulama kullansalar da, "yeni" uygulamayı kullanmak için "yeni" yi kullanan her çizgiyi değiştirmeli ve değiştirmeliler.
Fabrikalar - her şeyden daha iyi - bahar çerçevesi tamamen bu fikir etrafında inşa edilmiştir.
Fabrikalar bir soyutlama katmanıdır ve tüm soyutlamalar gibi, karmaşıklık içinde bir. Fabrikanın belirli bir API için ne olduğunu belirleyen fabrika tabanlı bir API ile karşılaşıldığında API tüketicisi için zor olabilir. Kurucular ile keşfedilebilirlik önemsizdir.
Klişeler ve fabrikalar arasında karar verirken, karmaşıklığın fayda ile doğrulanıp kaynaklanmadığına karar vermelisiniz.
Javascript kurucularının, bu ya da tanımlanmamış başka bir şey döndürerek keyfi fabrikalar olabileceğine dikkat çekmek gerekir. Yani js'de keşfedilebilir API ve nesne havuzlama / önbellekleme - her iki dünyanın en iyisini elde edebilirsiniz.