Cómo evitar captadores / definidores en clases con muchas variables de instancia

Intentaré que sea breve.

Tengo clases con muchas variables de instancia (30+) y, por lo tanto, muchos captadores / definidores. Las clases por sí mismas son simples, pero debido a los captadores / configuradores, el LOC acaba de explotar (y también había demasiada duplicidad de código).

Así que eliminé los atributos y los almacené en un mapa, como este

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 solía ser solo una cadena, pero de esta manera puedo garantizar el tipo de seguridad en el configurador. Ahora, mi pregunta, eliminé la duplicidad de código dentro de la clase, pero tengo otras clases que también tienen muchos atributos (porque representan algunos objetos técnicos ...), ¿cuál es el mejor enfoque aquí? ¿Para dar a cada clase su propia enumeración AttributeKey?

SOLUCIÓN

Agregué algunos pensamientos más. Tengo el tipo de seguridad ahora en tiempo de compilación. Aquí está mi nueva interfaz para el getter y setter.

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

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

Joshua Bloch llama a este tipo de concepto.contenedor heterogéneo de tipos seguros.

Respuestas a la pregunta(2)

Su respuesta a la pregunta