2017-08-24 5 views
1

J'essaie de créer une classe Holder pour différents objets à utiliser dans mon application, j'ai fini avec ce code qui fonctionne bien jusqu'à un certain point, le modèle de constructeur fonctionne bien pour l'option champs, mais je suppose que ce support pourrait être refactorisé d'accepter un certain nombre de paramètres arbitrairementComment utiliser correctement les génériques pour un détenteur

package pojos; 

public class Holder<T, R, S, U> { 
private final T t; 
private final R r; 

private final S s; 
private final U u; 


private Holder(final Builder<T, R, S, U> builder) { 
    this.t = builder.t; 
    this.r = builder.r; 
    this.s = builder.s; 
    this.u = builder.u; 
} 


public T getField1() { 
    return this.t; 
} 

public R getField2() { 
    return this.r; 
} 

public S getField3() { 
    return this.s; 
} 

public U getField4() { 
    return this.u; 
} 


public static class Builder<T, R, S, U> { 
    private T t; 
    private R r; 
    private S s; 
    private U u; 


    public Builder field1(final T t) { 
     this.t = t; 
     return this; 
    } 

    public Builder field2(final R r) { 
     this.r = r; 
     return this; 
    } 

    public Builder field3(final S s) { 
     this.s = s; 
     return this; 
    } 

    public Builder field4(final U u) { 
     this.u = u; 
     return this; 
    } 

    public Holder<T, R, S, U> build() { 
     return new Holder<>(this); 
    } 

    public Builder<T, R, S, U> copy(final Holder<T, R, S, U> rowMappingsHolder) { 
     this.t = rowMappingsHolder.getField1(); 
     this.r = rowMappingsHolder.getField2(); 
     this.s = rowMappingsHolder.getField3(); 
     this.u = rowMappingsHolder.getField4(); 
     return this; 
    } 


} 

}

Exemple d'utilisation:

protected Holder<Row, Map<Integer, String>, Void, Void> getRowMapHolder(Row row, Map<Integer,String> map) { 
    return (Holder<Row, Map<Integer, String>, Void, Void>) new Holder.Builder<Row, Map<Integer, String>,Void, Void>().field1(row).field2(map).build(); 
} 

tout id eas?

Cordialement

~ Marco

+0

"arbitrairement nombre de paramètres" ces paramètres sont du même type? –

+0

Non, comme vous pouvez voir le support peut contenir des objets de types différents, voir l'exemple d'utilisation n'utilise que les deux premiers, l'un contenant un type "Row" et le second contenant un objet de type "Map". question ici, est comment créer un titulaire où nous pouvons passer plusieurs types et les récupérer dans l'ordre où ils ont été insérés dans le Titulaire, donc plus de "field1", "field2" ... –

+0

Si vous n'avez pas une structure explicite/collection de valeurs que vous essayez de maintenir, il est beaucoup plus facile d'utiliser un Map ou un Set comme porteur et de lancer une exception d'argument invalide si quelque chose sur ce support est malformé (paramètre requis manquant ou quelque chose) – Tezra

Répondre

0

Merci aux commentaires de Andy et Google Autovalue, une bonne solution ont été soulevées:

Ainsi, nous pouvons créer différentes catégories qui ont un sens, pas plus "field1", "field2" ...

package pojos; 

import com.google.auto.value.AutoValue; 
import org.apache.poi.ss.usermodel.Row; 

import java.util.Map; 

@AutoValue 
public abstract class RowMapHolder { 

    public abstract Row row(); 

    public abstract Map<Integer,String> mapping(); 

    public static RowMapHolder create(Row row, Map<Integer, String> mapping) { 
     return new AutoValue_RowMapHolder(row, mapping); 
    } 

} 

ou

package pojos; 

import com.google.auto.value.AutoValue; 

import java.util.List; 
import java.util.Map; 

@AutoValue 
public abstract class KeyValuesMapHolder { 

    public abstract List<KeyValue<String,String>> keyValues(); 
    public abstract Map<Integer,String> mapping(); 

    public static KeyValuesMapHolder create(List<KeyValue<String, String>> keyValues, Map<Integer, String> mapping) { 
     return new AutoValue_KeyValuesMapHolder(keyValues, mapping); 
    } 

} 
1

Comment cela devrait fonctionner pour le nombre de paramètres différents? Vous avez un nombre fini d'accesseurs, donc vous ne pouvez pas utiliser, par exemple, h.getField2147(), si vous ne le déclarez pas.

Une autre façon d'avoir un tuple pour un nombre différent d'objets est un tableau hétérogène. En Java, ofc, vous pouvez simplement utiliser Object[] et vous pouvez envelopper avec classe, qui ont des méthodes

public <T> T getField(int i) { 
    return (T) arr[i]; 
} 

puis utiliser comme h.<String>getField(2147)

Mais la création de différentes classes pour tuples de taille différente (comme votre pour 4 objets) est meilleur.