2010-08-03 8 views
5

Belirli bir arabirimi uygulayan bazı nesneler oluşturma gereksinimim var; oluşturulan somut uygulamanın türü Enum değerine dayanıyor.Fabrika Deseni benim sorunumu çözecek mi?

Farklı beton uygulamaları çalışma zamanında farklı parametreler gerektirdiğinde sorun yaşıyorum.

Bu örnek (C#) gayet: Ancak

public enum ProductCategory 
{ 
    Modem, 
    Keyboard, 
    Monitor 
} 

public class SerialNumberValidatorFactory() 
{ 
    public ISerialNumberValidator CreateValidator(ProductCategory productCategory) 
    { 
     switch (productCategory) 
     { 
      case ProductCategory.Modem: 
       return new ModemSerialNumberValidator(); 
      case ProductCategory.Keyboard: 
       return new KeyboardSerialNumberValidator(); 
      case ProductCategory.Monitor: 
       return new MonitorSerialNumberValidator(); 
      default: 
       throw new ArgumentException("productType", string.Format("Product category not supported for serial number validation: {0}", productCategory)) 
     } 
    } 
} 

, beton uygulamaları farklı yapıcı argümanları varsa ne olur? Tüm değerleri SerialNumberValidatorFactory.CreateValidator() yöntemine iletemiyorum, nasıl devam edeceğim?

Abstract Factory örneğinin bunu çözmesi gerektiğini duydum ancak düzgün şekilde nasıl uygulanacağından emin değilim.

+0

Bunun yerine, yapıcı parametrelerini arabirimde bir başlatma yöntemi içine toplayabilir misiniz? Bu size parametresiz bir kurucu ile bırakacaktır. Kurucu parametrelerinin tanımlanması, arayanın argümanları sağlaması gerektiği anlamına gelecektir (fabrika bunları sağlayamadığı sürece), arayanın şimdi bir uygulamaya özgü bir şeyler sağlaması nedeniyle bir arayüzün kullanılması noktasını kıstırır. –

+0

@Adam Evet Bunu düşündüm. Tek şey daha sonra 'Initialise() 'çağrısını denetliyor. En azından ctor args'lar ile, bunlar girmekten kaçınamayacağınız * gerekli * değerlerdir. –

+0

Her zaman daha fazla arabirim katmanı ekleyebilirsiniz - belirli bir tür için argümanları içeren 'Ayarlar 'sınıfı. Ardından, ayarları isteyen ve bunu "FactoryValidator" sınıfındaki fabrikaya ileten her doğrulayıcı için bir "ISettings" gösterebilirsiniz. Bu, başka bir arabirime yazılan değerleri geçirdiğiniz anlamına gelir - bu nedenle, bu arabirime bağlı olduğunuza inanıyorum, ancak 'ProductType' kodunuzu geçirmeniz bile belirli bir tür beklemekte olduğundan, belirli bir arabirimi geçirmeniz zarar vermeyecektir daha fazla –

cevap

2

CreateValidator yöntemine geçmek için her zaman bir Ayarlar kabı oluşturabilirsiniz. Bir IValidatorSettings tabanı ile başlayın, ardından , CreateValidatorProductType ve IValidatorSettings argümanlarını alabilir.

Doğrulayıcılar için somut sınıflarınız, tek kurucu argümanı olarak IXXXValidatorSettings arabirimini alır.

Bundan başka, IValidatorSettings fabrika oluşturabilirsiniz.

Bence soyut fabrika, belirli bir tür kümeyi işlemek için bir fabrika oluşturan bir fabrikadır - senaryoda geçerli olup olmadığından emin değil. Bir Fabrika Yöntemi desen kullanılarak Ne

2

, ne kullanmalıyım soyut fabrikada bir Özet Fabrikası

olduğunu, her somut uygulama için bir fabrika sınıfı sağlar:

Yani kod olur

: (kodu affet, ama mantık aynıdır)

public class SerialNumberValidatorFactory 
{ 
    public static SerialNumberValidatorFactory newInstance(
      ProductCategory productCategory) 
    { 
     switch (productCategory) 
     { 
      case ProductCategory.Modem: 
       return new ModemValidatorFactory(); 
      .... 
     } 
    } 

    public abstract ISerialNumberValidator createValidator(); 
} 

public class ModemValidatorFactory extends SerialNumberValidatorFactory 
{ 
    public ISerialNumberValidator createValidator() 
    { 
     return new ModemSerialNumberValidator("model", "number"); 
    } 
} 

ISerialNumberValidator = SerialNumberValidatorFactory.newInstance(productCategory).createValidator()