2013-08-07 12 views
5

Próbuję utworzyć wzorzec konstruktora, który używa generycznych, aby zapewnić sprawdzanie typów na niektórych metodach. Obecnie mam następujący robocza:Generic Type From Enum & The Builder Pattern

ParameterBuilder.start(String.class).setName("foo").setDefaultValue("Hello").build(); 
ParameterBuilder.start(Integer.class).setName(bar).setDefaultValue(42).build(); 
ParameterBuilder.start(Boolean.class).setName(bar).setDefaultValue(false).build(); 

Używanie kod:

public class ParameterBuilder<T> { 
    private String name; 
    private T defaultValue; 

    public static <T2> ParameterBuilder<T2> start(Class<T2> type) { 
    return new ParameterBuilder<T2>(); 
    } 
    // Other methods excluded for example 
} 

Więc rodzaj wejścia dla metody setDefaultValue jest zdefiniowana przez co przeszła w sposobie start, tak jak chcę.

Ale teraz chcę rozszerzyć to, co jest przekazywane do start(), aby zawierało trochę więcej informacji. Zasadniczo chcę przekazać "typ" dla parametrów, które tworzę. Czasami te parametry będą takie rzeczy jak „email”, „URL” itp Domyślna wartość nadal będzie typu znane (String w tych przypadkach), więc chciałbym mieć coś takiego:

ParameterBuilder.start(EMAIL).setName("email").setDefaultValue("[email protected]").build(); 
ParameterBuilder.start(URL).setName("website").setDefaultValue("http://www.somewhere.com").build(); 

Adresy URL EMAIL & są wyliczeniami, zawierającymi między innymi - klasę wartości domyślnej. Ale jeśli pójdę tą drogą, w jaki sposób mogę utworzyć instancję konstruktora parametrów?

public static <T2> ParameterBuilder<T2> start(ParameterType paramType) { 
    Class<T2> type = paramType.getTypeClass(); 
    // How do I instantiate my ParameterBuilder with the right type? 
} 

Jeśli nie można zrobić za pomocą teksty stałe (które mogę zobaczyć bycia przypadku), czy ktoś ma propozycję dla innego rozwiązania?

+1

można pokazać, co dokładnie jest 'EMAIL',' URL'. Czy są to 2 różne wyliczenia? Czy są to przypadki dwóch wyrażeń? Czym oni są? –

+0

W moim przypadku miałem ParameterType echoing coś w stylu: 'public enum ParameterType {STRING (String.class," String "), INTEGER (Integer.class," Integer "), MULTILINE (String.class," Multine Text "), HTML (String.class, "HTML"), DATE (Date.class, "Date"), BOOLEAN (Boolean.class, "Boolean"); // Metody zastosowane " –

Odpowiedz

2

myślę, że trzeba za jeden enum typu klasy (I nie rozumiem, jak można mieć obejmować jedno enum kilka rodzajów i utrzymać pracę rzecz). W takim przypadku wspólny interfejs ogólny może zrobić to, co chcesz. Możesz wtedy stworzyć fabrykę, która zapewni stałe enum, jeśli to pomoże.

To kompiluje:

static interface ParameterType<T> {} 

static enum ParameterTypeEnum implements ParameterType<String> { EMAIL; } 

public static void main(String[] args) { 
    ParameterBuilder 
      .start(ParameterTypeEnum.EMAIL) 
      .setName("email") 
      .setDefaultValue("[email protected]") 
      .build(); 
} 

public static class ParameterBuilder<T> { 

    private String name; 
    private T defaultValue; 

    public static <T2> ParameterBuilder<T2> start(ParameterType<T2> paramType) { 
     return new ParameterBuilder<T2>(); 
    } 

    ParameterBuilder<T> setName(String name) { 
     this.name = name; 
     return this; 
    } 

    ParameterBuilder<T> setDefaultValue(T defaultValue) { 
     this.defaultValue = defaultValue; 
     return this; 
    } 

    void build() {} 
} 
+0

To brzmi jak rozsądny sposób robienia tego. W ten sposób mógłbym mieć StringParameterEnum, IntegerParameterEnum itp., Który nadal pozostawi kod całkiem czysty. Dzięki –

0

Nie jestem pewien kontekst, w którym chcesz tego użyć, ale myślę, że następujące może być opcja.

Można postępować zgodnie z zasadą Otwarty/Zamknięty i utworzyć interfejs Parameter i mieć jedną implementację dla każdego typu. Zaletą tego jest to, że nie musisz dodawać nowej wartości wyliczeniowej dla każdego nowego parametru, który chcesz. Możesz później przekazać klasę do ParameterBuilder zamiast enum, a i Parameter będą działać razem, aby zbudować to, czego potrzebujesz.

Tak więc ParameterBuilder.start() może zwrócić wystąpienie określonego Parameter, a parametr może mieć różne metody w zależności od typu parametru.

Nie sądzę, to odpowiedź jest bardzo dobra, ale mam nadzieję, że może dać wskazówkę, w jaki sposób budować potencjalne rozwiązanie dla swojego kontekstu.

0

Można utworzyć hierachie obiektu dla tych e-mail i adres URL typów

public class DefaultType { 
    protected String name; 
    protected String defaultValue; 
    //some constructor 
} 

public class EmailType extends DefaultType { 
    ... 
} 

public class URLType extends DefaultType { 
    ... 
} 

następnie budowniczym parametr może wyglądać mniej więcej tak:

public static ParameterBuilder start(DefaultType type) { 
    ParameterBuilder builder = new ParameterBuilder(type); 
    builder.setType(type); 
    return builder; 
} 

Następnie można nazwać to tak:

ParameterBuilder.start(new EmailType("name","value");... 

czyni tę pomoc lub nie chcesz iść w tym kierunku?