Ho un'interfaccia, Attribute
, che sarà implementata in vari modi,
class AttributeA implements Attribute{\..}
class AttributeB implements Attribute{\..}
Quindi ho intenzione di avere una classe contenente un elenco di membri dell'interfaccia
class Example {
List<Attribute> attributes;
//..
}
E poi ho intenzione di avere una classe contenente un elenco di quelli
class ExamplesAndMore {
List<Example> examples;
//..
}
Ma, voglio ogni instatiation di ExamplesAndMore
per assicurarmi che ci siano solo esempi dello stesso tipo o firma. Cioè, voglio assicurarmi che la lista examples
non contenga un membro la cui lista attributes
abbia la forma <AttributeA, AttributeA, AttributeB>
mentre un'altra è di <AttributeA, AttributeA, AttributeA>
o <AttributeA, AttributeA, AttributeB, AttributeB>
.
Potrei controllare ovunque io modifichi la lista examples
.
Un commento mi ha chiesto di essere più specifico, quindi fornirò il codice per sapere come farlo.
class Example {
List<Attribute> attributes;
public List<Class<? extends Attribute>> getSignature(){
List<Class<? extends Attribute>> result = new ArrayList<Class<? extends Attribute>>();
for(Attribute attribute : attributes){
result.add(attribute.getClass());
}
return result;
}
//..
}
public class ExamplesAndMore {
List<Example> examples;
List<Class<? extends Attribute>> signature;
public ExamplesAndMore(List<Class<? extends Attribute>> signature){
this.signature = signature;
this.examples = new ArrayList<Example>();
}
public void addExample(Example example){
if(!example.getSignature().equals(signature)){
throw new IllegalArgumentException(String.format("This takes examples with signature %s", signature.toString()));
}
examples.add(example);
}
//..
}
Ma mi chiedo se questo è un buon modo per farlo, controllare i tipi in fase di esecuzione non è piacevole. Fondamentalmente penso che questo codice abbia un odore un po '. Un modo in cui questo odore potrebbe manifestarsi come un problema reale è quando creo
class GenericAttribute<T> implements Attribute{\..}
con l'intenzione di non avere un esempio con un attributo di tipo GenericAttribute<ClassA>
e uno di tipo GenericAttribute<ClassB>
nella stessa lista. Quindi digita le rovine della mia giornata.
Inoltre, quando non ho bisogno di esempi per contenere arbitrariamente molti attributi ma solo un numero fisso (diciamo 3), allora il mio problema scompare completamente e posso anche verificare in fase di compilazione avendo
class Example<T1, T2, T3> {
//..
}
public class ExamplesAndMore<T1,T2,T3> {
List<Example<T1,T2,T3> examples;
public void addExample(Example<T1,T2,T3> example){\..}
//..
}
Tuttavia, questo approccio ovviamente non si estende agli esempi con arbitrariamente molti attributi.
Ad ogni modo, sento che mi manca qualche tecnica ovvia o qualcosa del genere. C'è un bel modello che si occupa di questo, sto progettando male questo? È probabile che io non sia il primo a farlo.
Mi dispiace anche per il titolo schifoso, Se avessi una descrizione migliore del mio problema, probabilmente avrei avuto più fortuna a cercare una risposta e non avrei dovuto chiedere ...