2015-01-16 31 views
6

"Etkin Java" bölümünde yer alan "Oluşturucu Kalıbı" ile ilgili bir sorum vardı. Deseni doğru bir şekilde uygulamak için .build() yöntemine ihtiyacımız var mı?Builder Kalıbında bir .build() yöntemine mi ihtiyacımız var?

public class CoffeeDrink { 

    private int numEspressoShots; 
    private short milkType; 
    private boolean withWhip; 

    private CoffeeDrink() { 
    } 

    public static CoffeeDrink buildNewDrink() { 
     return new CoffeeDrink(); 
    } 

    public CoffeeDrink withEspresso(int n) { 
     this.numEspressoShots = n; 
     return this; 
    } 

    public CoffeeDrink withMilkType(shot t) { 
     this.milkType = t; 
     return this; 
    } 

    public CoffeeDrink withWhip() { 
     this.withWhip = true; 
     return this; 
    } 
} 

Sonra nasıl kullandığımız: Bir statik iç Builder sınıfı yoksa

CoffeeDrink c = CoffeeDrink.buildNewDrink() 
         .withEspresso(2) 
         .withMilkType(2) 
         .withWhip(); 

bu hala geçerli olur Örneğin, en aşağıda belirtilen sınıf var diyelim? Avantajlarından biri, nesnesini .build() yönteminin çağrılıncaya kadar tutmaya devam etmesidir, ancak hala bir Builder nesnesi oluşturuyorum. Sadece bazı açıklamalar arıyorum.

+1

Oluşturucu Desen değişmez sınıfları ile çok avantajlı bir şekilde kullanılır. Onlarla birlikte, Builder, daha sonra immutable olan nihai ürünün nihai yapımında yardımcı olan değişken bir "yardımcı" sınıfıdır. Örneğiniz sadece basit bir POJO'dur ve JavaBeans'in dezavantajlarını paylaşır (değişken, eksik veya tutarsız bir durumda görülebilir). – scottb

cevap

14

Hayır, bu Builder kalıbı değil. Bu geçerli bir Java ve derleyip çalıştıracaktır. Ancak, build() veya buildNewDrink() ya da başka bir şey olarak adlandırılan buildNewDrink() yönteminiz, CoffeeDrink oluşturan basit bir Fabrika Yöntemi'dir. Bu diğer yöntemler, kendilerini geri döndüren belirleyici yöntemler gibidir.

İç içe geçmiş Builder sınıfı static gereklidir. Sınıf örneğini oluştururken beklerken, geçersiz bir nesnenin oluşturulmadığından emin olmak için doğrulama mantığı gerçekleştirebilir. CoffeeDrink için geçersiz bir durum olduğundan emin değilim, ancak eğer kodunuz varsa, bir CoffeeDrink oluşturmak ve oluşturulduktan sonra geçersiz bir duruma sahip olmak, ancak önce diğer yöntemler çağrıldı. Oluşturucu modeli, örneği oluşturmadan önce verileri doğrulayarak bu olasılığı ortadan kaldırır. Ayrıca olası tüm durumları kapsayacak şekilde olası tüm parametre kombinasyonlarına sahip birçok kurucuya ihtiyaç duyulan kurucu patlamasına olan ihtiyacı ortadan kaldırır.

+0

Düşüncelerinize katılıyorum. Bu yöntemler * zincirleme * ile düzenli belirleyiciler gibi görünüyor. Sadece küçük bir ayrıntı var, ama cevapta * "değil" * yanıtınız eksik olabilir. * "Geçersiz bir nesnenin ** oluşturulmadığından emin olmak için doğrulama mantığını uygulayabilir" *. – afsantos

+0

@afsantos Teşekkürler; düzeltildi. – rgettman

+0

Açıklamalar için teşekkürler. Bu yüzden, CoffeeDrink örneğini döndürmeden önce, Builder sınıfının oluşturucu işlevindeki tüm parametreleri doğrulayabilir miyim? – victormejia

1

GoF referansına göre, build() gerekli değildir. Özgün başvuru zincirleme kullanmıyor ve Director.construct() yönteminin sonunda bir getResult() adım var. Director sınıfı, yapım sürecini kapsüllemekle ilgilenir, bu nedenle Client un, işleri doğru bir şekilde oluşturuyorlarsa endişelenmelerine gerek yoktur. Bu, Director'un sorumluluğundadır.

Burada Builder GoF referans sekansı diyagramı verilmiştir:

GoF Builder Sequence Diagram