Wie vermeide ich Getter / Setter in Klassen mit vielen Instanzvariablen?

Ich werde versuchen, es kurz zu halten.

Ich habe Klassen mit vielen Instanzvariablen (30+) und daher viele Getter / Setter. Die Klassen an sich sind einfach, aber aufgrund der Getter / Setter explodierte das LOC gerade (und es gab auch viel zu viel Code-Duplizität).

Also entfernte ich die Attribute und speicherte sie wie folgt in einer Map

public class MyTechnicalToolClassX
{

//...constructor

private Map<String, Object> data;

public Object getAttributeByKey(AttributeKey key)
{
    // ...doStuff, check data associated with key, etc
    // if (predicate == true) return otherData;
    return data.get(key.toString());
}

public void setAttributeByKey(AttributeKey key, Object value) throws IllegalArgumentException
{
    if(key.getType().isInstance(value))
    {
        data.put(key.toString(), value);
    }
    else
    {
        throw IllegalArgumentException("The passed value has the wrong type, we expect: "
        + key.getType().getName());
    }
}

public enum AttributeKey
{
    someKey1("key1", String.class),
    someKey2("key2", Date.class),
    //...
    someKeyN("keyN", SomeType.class);

    private String key;
    private Class valueType;

AttributeKey(String key, Class valueType)
{
    this.key = key;
    this.valueType = valueType;
}

@Override
public String toString()
{
    return key;
}

public Class getType()
{
    return valueType;
}

} // AttributeKey

} // MyTechnicalToolClassX

AttributeKey war früher nur eine Zeichenfolge, aber auf diese Weise kann ich die Typensicherheit im Setter gewährleisten. Nun meine Frage, ich habe die Code-Duplizität innerhalb der Klasse entfernt, aber ich habe andere Klassen, die auch viele Attribute haben (weil sie einige technische Objekte darstellen ...), was ist der beste Ansatz hier? Um jeder Klasse eine eigene AttributeKey-Aufzählung zu geben?

LÖSUNG

Ich fügte noch ein paar Gedanken hinzu. Ich habe jetzt Typensicherheit zur Kompilierungszeit. Hier ist meine neue Schnittstelle für den Getter und Setter.

public <Type, SetVal extends Type> void setAttributeByName(IAttribute<Key, Type> attribute, SetVal value);

public <Type> Type getAttributeByName(IAttribute<Key, Type> attribute);

Joshua Bloch nennt diese Art von Konzepttypsichere heterogene Container.

Antworten auf die Frage(2)

Ihre Antwort auf die Frage