Ne gibi şeyler iyi bir kurucu bitmedi?

12 Cevap php

Ben bir soru hazırlanması ile başladı: "Ne bir kurucu üzerinde birim test gerçekleştirmek için en iyi yolu (örneğin, __ PHP5'ta construct ())", ancak ilgili soruları okurken, ben bu ayarı önermek gibiydi birkaç yorum gördüm üye değişkenler veya yapıcı herhangi bir karmaşık işlemleri gerçekleştirmek no-no vardır.

Burada söz konusu sınıf için yapıcı bir param alır, ve daha sonra bir üye değişkeni içinde uzak miktarlarsa (emin bir sniff testi ve gerekirse dönüştürerek geçer yapma) üzerinde bazı işlemleri gerçekleştirir.

Ben bu şekilde yapmanın yararları sanıyordum:

1) that client code would always be certain to have a value for this member variable whenever an object of this class is instantiated, and

2) it saves a step in client code (one of which could conceivably be missed), e.g.,

$Thing = new Thing;
$Thing->initialize($var);

biz sadece bu yapabileceğini zaman

$Thing = new Thing($var);

ve onunla yapılabilir.

Bu bir hayır-hayır mı? Öyleyse neden?

12 Cevap

Bu C + + tartışmalarda oldukça çok gelir, ve ben geldim genel sonuç bu olmuştur:

Bir nesne herhangi bir dış kaynak elde etmezse, üyeler must başlatıldı in yapıcı olun. Bu yapıcısı bütün işi gerektirir.

  • (X, y) koordinatı (ya da gerçekten sadece bir yüceltilmiş başlığın bulunuyor başka bir yapı)
  • ABD devlet kısaltma arama tablosu

Bir nesne kontrol edebilirsiniz kaynaklarını edinirse, onlar may tahsis in yapıcı edilebilir:

  • açık dosya tanımlayıcı
  • ayrılan bellek
  • harici bir kütüphane içine / tanıtıcısı

Nesne kaynakları elde o olamaz, tamamen kontrolü, onlar must outside yapıcı tahsis edilecek olursa:

  • TCP bağlantısı
  • DB bağlantısı
  • zayıf referans

Orada istisnalar her zaman vardır, ancak bu çoğu durumlarda kapsar.

Zaman kural yapıcı bittikten sonra bir nesne kullanıma hazır olmasıdır. Ama daha sonra tweaked olabilir bir dizi seçenek genellikle vardır.

Benim yapılacak ve Donts listesi:

  • Kurucular nesne için temel seçenekleri kurmak gerekir.
  • Onlar belki yardımcı nesnelerin örneklerini oluşturmak gerekir.
  • Onlar gerekir not aqquire kaynakları (dosyalar, prizler, ...), nesne açıkça bazı kaynak etrafında sarıcı sürece.

Tabii ki, istisna olmadan kural yok. Önemli olan sizin tasarım ve seçimlerle ilgili düşünüyorum. Nesne kullanımı doğal olun - ve bu hata raporlama içerir.

Oluşturucular nesneyi başlatmak için, bu yüzden

$Thing = new Thing($var);

mükemmel kabul edilebilir.

Bir kurucu işi bir örneğinin invariants kurmaktır.

Buna katkıda bulunmaz şey iyi yapıcısı dışında tutulur.

Bir sınıfın edilebilirliğini artırmak için mümkün olduğunca basit bu yapıcısı tutmak ve bunu kesinlikle ihtiyacı şeyler için sadece sormak için genelde iyi bir şeydir. Ayrıntılı olarak bu açıklayan Google'ın "Temiz Kod Konuşmaları" serisinin bir parçası olarak YouTube'da mükemmel bir presentation mevcut bulunuyor.

Kesinlikle müşteri aramak zorunda yapılmasından kaçınılmalıdır

$thing->initialize($var)

Öyle şeyler kesinlikle kurucusuna aittir. Onları bu arama yapmak için müşteri programcı sadece düşmanca bulunuyor. Orada nesneleri geçersiz bir durumda never olduğunu böylece sınıflar yazmak gerektiğini söylüyor düşünce (biraz tartışmalı) okul - ve 'başlatılmamış' geçersiz bir durumdur.

Ancak test edilebilirlik ve performans nedenleriyle, bazen daha sonra nesnenin hayatında kadar belli baþlatma erteleme iyi. Bu gibi durumlarda, tembel değerlendirme çözümdür.

Python cevap Java sözdizimi koymak için özür dilemek istiyorum ama:

// Constructor
public MyObject(MyType initVar) {
      this.initVar = initVar;
}

private void lazyInitialize() {
    if(initialized) {
        return
    }
    // initialization code goes here, uses initVar
}

public SomeType doSomething(SomeOtherType x) {
    lazyInitialize();
    // doing something code goes here
}

Bu segmentte tembel başlatma yapabilirsiniz böylece başlatılmış olsun gerek sadece parçalar. Bu sadece var varlık değerini etkiler ne için, alıcılar bunu yapmak, örneğin, yaygın.

Ben dahil hiçbir zincirleme var, özellikle eğer, ben bir sürükle biraz olmak ayrı yöntem kullanılarak argümanları sürü temin bulamıyorum neden görmüyorum.

Eğer mimar için çalışıyoruz sisteminin ne tür bağlıdır, ama genel olarak ben Kurucular iyi yalnızca nesnenin "devlet" başlatılıyor için kullanılan, ancak kendilerini geçişler herhangi bir devleti gerçekleştirmek değildir inanıyoruz. İyi sadece varsayılan ayarlamak var.

Sonra kullanıcı girişi, veritabanı aramaları, istisnalar, harmanlama, ne gibi şeyler işlemek için benim nesneler içine bir "kulp" yöntemi yazmak. Fikir bu nesnenin dış güçlerin (kullanıcı girişi, zaman, vb) dayalı kendini bulur ne olursa olsun devlet Temelde, nesnenin durumunu değiştirmek ve ek bir işlem gerektirebilir her şey keşfetti ve temsil edilmektedir idare edecek olmasıdır nesnesi.

Son olarak, anlamlı bir kullanıcı bir şey göstermek için sınıfa render yöntemi koymak. Bu yalnızca (yani ne olursa olsun.) Kullanıcıya nesnenin durumunu temsil

__construct($arguments)
handle()
render(Exception $ex = null)

__ Sihirli yöntem kullanmak için gayet iyi yaparız. Bu nesne bir arayüze programlanmış ediliyor ya da bir singleton / getInstance deseni çıkarmak için çalışıyor çünkü çerçeveler ve uygulamalar bir sürü başlatmak görmek nedenidir.

Bu nesneler genelde bağlamında veya bir denetleyicisi içine çekti ve daha sonra diğer yüksek düzey nesneler tarafından kendilerine çağırdı ortak arayüz işlevi vardır.

$ Var $ Şey çalışması için kesinlikle gerekli ise, o zaman bir DO olduğunu

Dependency Injection Bu makale yapıcı sorunuyla ilgili oldukça yararlı olduğunu. Ve nesne örnekleme (ve dış bağımlılıkları kurmak için gereken belirleyiciler paketi) bir fabrika nesnesine temsilci - Özetle, yazar nesnelleştirilmesi de dış kaynaklardan bir sınıf ayrılabilmesi için belirleyiciler kullanılmasını önerir.

http://www.potstuck.com/2009/01/08/php-dependency-injection/

Sadece sınıf oluşturulduğunda kez çalıştırmak gerekiyordu yapıcı şeyler koymak gerekir.

Açıklamak.

If i had a database class. Where the constructor is the connection to the database So

$db = new dbclass;

Ve şimdi ben veritabanına bağlı duyuyorum.

Sonra veritabanı sınıfının içinde bazı yöntemler kullanan bir sınıf var.

class users extends dbclass
{
    // some methods
}

$users = new users 
// by doing this, we have called the dbclass's constructor again