Aslında oldukça basit:
Kurulumunuzu yapan bir Yapıcıya sahip olmak yerine,
// c-family pseudo-code
public class Thing {
public Thing (a, b, c, d) { this.x = a; this.y = b; /* ... */ }
}
... hiç veya çok az şey yapmak senin yapıcı olması ve adlı bir yöntem yazmak .init
veya .initialize
sizin yapıcı normalde ne yapacağını yapardı.
public class Thing {
public Thing () {}
public void initialize (a, b, c, d) {
this.x = a; /*...*/
}
}
Şimdi sadece şöyle gitmek yerine:
Thing thing = new Thing(1, 2, 3, 4);
Gidebilirsin:
Thing thing = new Thing();
thing.doSomething();
thing.bind_events(evt_1, evt_2);
thing.initialize(1, 2, 3, 4);
Bunun yararı, artık bağımlılık-enjeksiyon / kontrolün ters çevrilmesini sistemlerinizde daha kolay kullanabilmenizdir.
Demek yerine
public class Soldier {
private Weapon weapon;
public Soldier (name, x, y) {
this.weapon = new Weapon();
}
}
Sen asker inşa edebilirsiniz, ona bir donatmak yöntemini vermek el ona silah ve SONRA yapıcı fonksiyonlarının geri kalan tüm diyoruz.
Şimdi, bir askerin tabancasına, diğerinin tüfeğe, diğerinin de av tüfeğine sahip olduğu düşmanları alt sınıflara ayırmak yerine, tek fark bu diyebilirsiniz:
Soldier soldier1 = new Soldier(),
soldier2 = new Soldier(),
soldier3 = new Soldier();
soldier1.equip(new Pistol());
soldier2.equip(new Rifle());
soldier3.equip(new Shotgun());
soldier1.initialize("Bob", 32, 48);
soldier2.initialize("Doug", 57, 200);
soldier3.initialize("Mike", 92, 30);
Yıkımla aynı anlaşma. Özel gereksinimleriniz varsa (olay dinleyicilerini kaldırma, dizilerden örnekleri / birlikte çalıştığınız yapıları vb. Kaldırma), daha sonra bunları manuel olarak çağırırsınız, böylece programın ne zaman ve nerede olduğunu tam olarak bilirsiniz.
DÜZENLE
Kryotan'ın işaret ettiği gibi, bu, orijinal yayının "Nasıl" yanıtını verir , ancak "Neden" için gerçekten iyi bir iş çıkarmaz.
Yukarıdaki cevapta görebileceğiniz gibi, arasında çok fazla bir fark olmayabilir:
var myObj = new Object();
myObj.setPrecondition(1);
myObj.setOtherPrecondition(2);
myObj.init();
ve yazma
var myObj = new Object(1,2);
sadece daha büyük bir yapıcı işlevine sahip.
15 veya 20 ön koşulu olan, bir kurucuyu çalışmak çok zorlaştıracak ve bu şeyleri arayüze çekerek işlerin görülmesini ve hatırlanmasını kolaylaştıracak bir argüman var. , böylece somutlaştırmanın nasıl çalıştığını, bir seviye daha yüksek olduğunu görebilirsiniz.
Nesnelerin isteğe bağlı konfigürasyonu bunun doğal bir uzantısıdır; isteğe bağlı olarak, nesneyi çalıştırmadan önce arabirimdeki değerleri ayarlama.
JS'nin bu fikir için, daha güçlü yazılan c-benzeri dillerde yerinden çıkmış gibi görünen bazı harika kısayolları var.
Bununla birlikte, şansınız, kurucunuzda bu kadar uzun bir argüman listesi ile uğraşıyorsanız, nesnenizin çok büyük ve olduğu gibi çok fazla şey yapmasıdır. Yine, bu kişisel tercihli bir şeydir ve uzak ve geniş istisnalar vardır, ancak bir nesneye 20 şey geçiriyorsanız, daha küçük nesneler yaparak o nesneyi daha az yapmanın bir yolunu bulma şansınız yüksektir. .
Daha uygun bir neden ve yaygın olarak uygulanabilir bir neden, bir nesnenin başlatılmasının şu anda sahip olmadığınız asenkron verilere dayanmasıdır.
Nesneye ihtiyacınız olduğunu biliyorsunuz, bu yüzden yine de oluşturacaksınız, ancak düzgün çalışabilmesi için sunucudan veya şimdi yüklemesi gereken başka bir dosyadan verilere ihtiyacı var.
Yine, gerekli verileri devasa bir başlığa geçiriyor olsanız da, bir arayüz oluşturuyor olsanız da, nesneniz ve sisteminizin tasarımı için önemli olduğu kadar, kavram için gerçekten önemli değildir ...
Ancak nesneyi oluşturma açısından, böyle bir şey yapabilirsiniz:
var obj_w_async_dependencies = new Object();
async_loader.load(obj_w_async_dependencies.async_data, obj_w_async_dependencies);
async_loader
bir dosya adı veya bir kaynak adı ya da her neyse, bu kaynağı yükleyebilir - belki ses dosyaları veya görüntü verileri yükler ya da kaydedilmiş karakter istatistiklerini yükler ...
... ve sonra bu verileri geri besleyecekti obj_w_async_dependencies.init(result);
.
Bu tür dinamikler web uygulamalarında sıklıkla bulunur.
Bir nesnenin yapısında, daha üst düzey uygulamalar için gerekli değildir: örneğin, galeriler hemen yüklenebilir ve başlatılabilir ve daha sonra fotoğrafları akış olarak görüntüleyebilir - bu gerçekten asenkron başlatma değil, ancak daha sık görüldüğü yer JavaScript kitaplıklarında.
Bir modül diğerine bağlı olabilir ve bu nedenle bu modülün başlatılması, bağımlıların yüklenmesi tamamlanana kadar ertelenebilir.
Bunun oyuna özel örnekleri açısından gerçek bir Game
sınıf düşünün .
Neden arayamam .start
ya .run
oluşturucu içinde?
Kaynakların yüklenmesi gerekiyor - her şeyin geri kalanı hemen hemen tanımlandı ve iyi gidiyor, ancak oyunu bir veritabanı bağlantısı olmadan veya dokular, modeller veya sesler veya seviyeler olmadan çalıştırmayı denersek, özellikle ilginç bir oyun ...
... öyleyse, tipik olarak gördüklerimiz arasındaki farktır Game
, ancak "devam et" yöntemini .init
, yüklemeyi ayırmak için daha ilginç olan (veya tersine, başlatmayı daha da parçalayın, yüklü olan şeyleri ayarlama ve her şey ayarlandığında programı çalıştırma).