Enum innerhalb einer Klasse / anderes Konzept

Hallo zusammen,

ich habe bisher innerhalb verschiedener Entities (zB Customer) mir ein Enum angelegt, mit welchem ich weitere Infos über die vorhandenen Felder bekomme.
Bisher habe ich nun in jeder Klasse solch ein Enum erstellt.
Die Frage ist nun aber, ob ich das nicht eleganter lösen kann. Wenn ich die Getter + Setter, & Kontruktor des Enumns nicht in jeder Entity anlegen müsste, wäre das schon mal vorteilhafter... Also wenn ich nur die ersten 4 Zeilen pro Entity hätte (in dem Beispiel nur die Zeilen zur Deklarierung von; ACADEMIC_TITLE und CUSTOMER_NUMBER)...
Kann ich das Enum außerhalb der Klasse lagern?

Java:
////////////////////
    ////// FIELDS
    ////////////////////

    public enum EntityField {

        ACADEMIC_TITLE("ACADEMIC_TITLE", ENTITY_NAME_SPACE + "ACADEMIC_TITLE", ENTITY_NAME, "Akademischer Titel",
                "Kunde: Akademischer Titel", DataTypeEnum.TEXT, null, OperatorEnum.listAllStringOperator(), true), //
        CUSTOMER_NUMBER("CUSTOMER_NUMBER", ENTITY_NAME_SPACE + "CUSTOMER_NUMBER", ENTITY_NAME, "Kundennummer",
                "Kunde: Kundennummer", DataTypeEnum.TEXT, null, OperatorEnum.listAllStringOperator(), true), //

        /////////////////////////

        private String fieldName; // Feldname
        private String uniqueFieldName; // eindeutiger Name
        private String entity; // Entität
        private String languageName; // Name in entsprechender Sprache
        private String languageNameEntity; // Name in entsprechender Sprache (mit Entität davor)

        private DataTypeEnum fieldType; // Datentyp
        private Object fieldValue; // Vorbelegter Wert (bei Geschlecht Herr/Frau)
        private List<Object> fieldValueList; // Vorbelegter Wert (bei Geschlecht Herr/Frau)
        private List<OperatorEnum> operatorList; // Liste von Operatoren
        private boolean ruleRelevant; // Für Regel relevant

        /////////////////////////

        private EntityField(String fieldName, String languageName) {
            this.fieldName = fieldName;
            this.languageName = languageName;
        }

        private EntityField(String fieldName, String uniqueFieldName, String entity, String languageName,
                String languageNameEntity, DataTypeEnum fieldType, Object fieldValue, List<OperatorEnum> operatorList,
                boolean ruleRelevant) {
            this.fieldName = fieldName;
            this.uniqueFieldName = uniqueFieldName;
            this.entity = entity;
            this.languageName = languageName;
            this.languageNameEntity = languageNameEntity;
            this.fieldType = fieldType;
            this.fieldValue = fieldValue;
            this.operatorList = operatorList;
            this.ruleRelevant = ruleRelevant;
        }

        private EntityField(String fieldName, String uniqueFieldName, String entity, String languageName,
                String languageNameEntity, DataTypeEnum fieldType, List<Object> fieldValueList,
                List<OperatorEnum> operatorList, boolean ruleRelevant) {
            this.fieldName = fieldName;
            this.uniqueFieldName = uniqueFieldName;
            this.entity = entity;
            this.languageName = languageName;
            this.languageNameEntity = languageNameEntity;
            this.fieldType = fieldType;
            this.fieldValueList = fieldValueList;
            this.operatorList = operatorList;
            this.ruleRelevant = ruleRelevant;
        }

        public String getEntity() {
            return entity;
        }

        public void setEntity(String entity) {
            this.entity = entity;
        }

        public List<Object> getFieldValueList() {
            return fieldValueList;
        }

       ... Getter + Setter
    }

Danke für die Tipps
 
K

kneitzel

Also wieso Enum nicht einfach eine Map oder so?

Du könntest also die benötigten Informationen in eine Klasse packen: EntityDescription oder wie Du das auch immer nennen willst.
Und dann hast Du eine gemeinsame super Klasse, die dann ein Array oder eine Map mit den Beschreibungen vorsieht.

Ich habe bei einem ähnlich gelagerten Fall das in ein Array gepackt und habe dann Konstanten für den Zugriff definiert.
(Bei der Map hättest Du dann z.B. Zugriff über den Namen).

Was Du da etwas verlierst ist die Limitierung der Enums bezüglich neuer Elemente aber durch die Kapselung ist das eigentlich kein Thema.
 
Hm, verstehe nicht so ganz wie du das meinst...
Wichtig ist, dass ich innerhalb anderen Klassen schnell und einfach auf das Feld, inkl. der Informationen zugreifen kann...

Also ich greife bei anderen Klassen dann so jeweils zu:
Java:
if (ruleConditionComponent.getFieldName().equals([B]Customer.EntityField.CUSTOMER_GROUP.getUniqueFieldName())[/B]) {
Und so erstelle ich jeweils eine Liste dann, die ich in ein Objekt der Klasse: RuleFieldHelper stecke...

Java:
        for (EntityField e : entityFieldList) {

            // Für Regel gedacht?
            if (e.isRuleRelevant()) {
                list.add(new RuleFieldHelper(e.getUniqueFieldName(), e.getLanguageNameEntity(), e.getEntity(),
                        e.getFieldType().getFieldName()));
            }
        }
 
K

kneitzel

Also was ich meinte war sowas in der Art:

EntityFieldDescription hält die Informationen, die Du bisher in dem Enum hälst;
Java:
package entity;

public class EntityFieldDescription {
    private String fieldName; // Feldname
    private String uniqueFieldName; // eindeutiger Name
    private String entity; // Entität
    private String languageName; // Name in entsprechender Sprache
    private String languageNameEntity; // Name in entsprechender Sprache (mit Entität davor)

    public EntityFieldDescription(String fieldName, String uniqueFieldName, String entity, String languageName, String languageNameEntity) {
        this.fieldName = fieldName;
        this.uniqueFieldName = uniqueFieldName;
        this.entity = entity;
        this.languageName = languageName;
        this.languageNameEntity = languageNameEntity;
    }

    public String getFieldName() {
        return fieldName;
    }

    public void setFieldName(String fieldName) {
        this.fieldName = fieldName;
    }

    public String getUniqueFieldName() {
        return uniqueFieldName;
    }

    public void setUniqueFieldName(String uniqueFieldName) {
        this.uniqueFieldName = uniqueFieldName;
    }

    public String getEntity() {
        return entity;
    }

    public void setEntity(String entity) {
        this.entity = entity;
    }

    public String getLanguageName() {
        return languageName;
    }

    public void setLanguageName(String languageName) {
        this.languageName = languageName;
    }

    public String getLanguageNameEntity() {
        return languageNameEntity;
    }

    public void setLanguageNameEntity(String languageNameEntity) {
        this.languageNameEntity = languageNameEntity;
    }
}
Dann kann ein Entity natürlich ein Array mit den Beschreibungen halten sowie Methoden zum schnellen Zugriff:
Java:
package entity;

public class Entity {
    protected EntityFieldDescription[] fieldDescriptions;

    public String getFieldName(int fieldIndex) {
        return fieldDescriptions[fieldIndex].getFieldName();
    }

    public String getUniqueFieldName(int fieldIndex) {
        return fieldDescriptions[fieldIndex].getUniqueFieldName();
    }

    public String getEntity(int fieldIndex) {
        return fieldDescriptions[fieldIndex].getEntity();
    }

    public String getLanguageName(int fieldIndex) {
        return fieldDescriptions[fieldIndex].getLanguageName();
    }

    public String getLanguageNameEntity(int fieldIndex) {
        return fieldDescriptions[fieldIndex].getLanguageNameEntity();
    }
}
Und dann sieht Deine eigentliche Entity wie folgt aus:
Java:
package entity;

public class ExampleEntity extends Entity {

    public static final int FIELD_TEST_1 = 0;
    public static final int FIELD_TEST_2 = 1;

    public ExampleEntity() {
        fieldDescriptions = new EntityFieldDescription[]{
            new EntityFieldDescription(....), // Field Test 1
            new EntityFieldDescription(....)  // Field Test 2
        }
    }
}
Und dann kannst Du Dir die Eigenschaften alle holen indem Du halt z.B. getUniqueFieldName(FIELD_TEST_1) aufrufst. Aber Du hast dann eine Klasse Entity, in die Du Logik, die du auf den Entities generell benötigst, packen kannst.
 
Also was ich meinte war sowas in der Art:

EntityFieldDescription hält die Informationen, die Du bisher in dem Enum hälst;
Java:
package entity;

public class EntityFieldDescription {
    private String fieldName; // Feldname
    private String uniqueFieldName; // eindeutiger Name
    private String entity; // Entität
    private String languageName; // Name in entsprechender Sprache
    private String languageNameEntity; // Name in entsprechender Sprache (mit Entität davor)

    public EntityFieldDescription(String fieldName, String uniqueFieldName, String entity, String languageName, String languageNameEntity) {
        this.fieldName = fieldName;
        this.uniqueFieldName = uniqueFieldName;
        this.entity = entity;
        this.languageName = languageName;
        this.languageNameEntity = languageNameEntity;
    }

    public String getFieldName() {
        return fieldName;
    }

    public void setFieldName(String fieldName) {
        this.fieldName = fieldName;
    }

    public String getUniqueFieldName() {
        return uniqueFieldName;
    }

    public void setUniqueFieldName(String uniqueFieldName) {
        this.uniqueFieldName = uniqueFieldName;
    }

    public String getEntity() {
        return entity;
    }

    public void setEntity(String entity) {
        this.entity = entity;
    }

    public String getLanguageName() {
        return languageName;
    }

    public void setLanguageName(String languageName) {
        this.languageName = languageName;
    }

    public String getLanguageNameEntity() {
        return languageNameEntity;
    }

    public void setLanguageNameEntity(String languageNameEntity) {
        this.languageNameEntity = languageNameEntity;
    }
}
Dann kann ein Entity natürlich ein Array mit den Beschreibungen halten sowie Methoden zum schnellen Zugriff:
Java:
package entity;

public class Entity {
    protected EntityFieldDescription[] fieldDescriptions;

    public String getFieldName(int fieldIndex) {
        return fieldDescriptions[fieldIndex].getFieldName();
    }

    public String getUniqueFieldName(int fieldIndex) {
        return fieldDescriptions[fieldIndex].getUniqueFieldName();
    }

    public String getEntity(int fieldIndex) {
        return fieldDescriptions[fieldIndex].getEntity();
    }

    public String getLanguageName(int fieldIndex) {
        return fieldDescriptions[fieldIndex].getLanguageName();
    }

    public String getLanguageNameEntity(int fieldIndex) {
        return fieldDescriptions[fieldIndex].getLanguageNameEntity();
    }
}
Und dann sieht Deine eigentliche Entity wie folgt aus:
Java:
package entity;

public class ExampleEntity extends Entity {

    public static final int FIELD_TEST_1 = 0;
    public static final int FIELD_TEST_2 = 1;

    public ExampleEntity() {
        fieldDescriptions = new EntityFieldDescription[]{
            new EntityFieldDescription(....), // Field Test 1
            new EntityFieldDescription(....)  // Field Test 2
        }
    }
}
Und dann kannst Du Dir die Eigenschaften alle holen indem Du halt z.B. getUniqueFieldName(FIELD_TEST_1) aufrufst. Aber Du hast dann eine Klasse Entity, in die Du Logik, die du auf den Entities generell benötigst, packen kannst.
Was ist dann genau "fieldDescriptions" ?

Wie würde dieser Aufruf dann aussehen?

Java:
if (ruleConditionComponent.getFieldName().equals(Customer.EntityField.CUSTOMER_GROUP.getUniqueFieldName()))
 
K

kneitzel

Das Array fieldDescriptions speichert die Daten, die Du ins Enum gepackt hast. Daher hat es die gleichen Felder wie Dein Enum.

Bei dem Beispiel weiß ich nicht, was Dein ruleConditionComponent sein soll. Aber mir fällt gerade noch auf, dass ich da einen kleinen Fehler drin habe, denn ich habe es ja nicht statisch gemacht. Aber es macht ja keinen Sinn, dass da jede Instanz einer Entity wirklich eine eigene Instanz der EntityFieldDescription bekommt. Daher muss man das wohl noch etwas mehr umstellen, damit man es wirklich nutzen kann wie du es brauchst.

Evtl. ist es dann einfacher, wenn Du nur die Klasse EntityFieldDescription (oder wie ich die nannte) nimmst und du in den Klassen statt Enums einfach nur public final static EntitityFieldDescription CUSTOMER_GROUP_FIELD_DESC = new ..... definierst. Dann hättest du in der Klammer halt etwas wie Customer.CUSTOMER_GROUP_FIELD_DESC.getUniqueFieldName()
Also einfach Enum durch eine Klasse ersetzen und dann die benötigten Instanzen statt als Enum Elementen eben direkt als Konstanten in die Klasse nehmen.
 
Mal eine Variante mit Reflection:
Ich geh einfach mal von den Dingen aus, die im Enum stehen:
  • fieldName; // Feldname
    • bereits gegeben, eben der Name des Felds
  • uniqueFieldName; // eindeutiger Name
    • gegeben durch Klasse + Feld
  • private String entity; // Entität
    • gegeben durch Klasse
  • private String languageName; // Name in entsprechender Sprache
    • Statt direkt das ganze lokalisiert zu speichern, sollte nur ein key benutzt werden, der dann in der UI entsprechend aufgelöst wird
    • möglicher Key ist zb uniqueFieldName
  • private String languageNameEntity; // Name in entsprechender Sprache (mit Entität davor)
    • gleiche wie oben
  • private DataTypeEnum fieldType; // Datentyp
    • Gegeben durch den Typ des Feldes
  • private Object fieldValue; // Vorbelegter Wert (bei Geschlecht Herr/Frau)
    • Lösbar über eine Annotation, zB @DefaultValue(FEMALE)
  • private List<Object> fieldValueList; // Vorbelegter Wert (bei Geschlecht Herr/Frau)
    • Lösbar über eine Annotation, zB @DefaultValues({FEMALE, MALE, UNKOWN})
    • uU aber auch über den Typ klar, zB bei enums
  • private List<OperatorEnum> operatorList; // Liste von Operatoren
    • @Operations({...})
  • private boolean ruleRelevant;
    • wenn sich das nicht anders lösen lässt @RuleRelevant(true), uU aber zusammen mit Operations?
Überall, wo keine explizite Anntotation steht, kann man natürlich eine ergänzen - wenn nötig.


Oder, was uU auch sinnvoll sein kann: Entity und die Feld-Informationen gänzlich zu trennen. Das hängt aber eben sehr vom Anwendungsfall ab (den du nicht nennen möchtest...).
Wenn das zB zum Generieren von entsprechenden Such-Funktionen in der UI dienen soll, gibts zu den Klassen eine "Filter"-Klasse, die die jeweiligen Informationen enthält. Die eigentliche Entität bleibt dann ein einfaches POJO mit Funktionalität die im Model benötigt wird, die dazugehörende Filter-Klasse enthält die für die UI nötigen Informationen.

Java:
class Customer {
    String name;
}

class CustomerFilter implements Filter<Customer> {
    Field name = new StringField("name", "Customer", ...);
    
   List<Field> getFields() {
      return List.of(name, ...);
   }
}

Oder, noch ne andere Variante: statt "normalen" Feldern werden die alle gewrapped in einer Klasse, die die nötigen Informationen enthält. Ganz grob etwa:

Java:
class StringField {
    String value;
    String name;
    ...
}

class Customer {
    StringField name;
}


Aber: für eine wirklich sinnvolle Antwort bräuchte man eine abstrakte Beschreibung des Problems. Anhand bestehender Codeschnipsel lässt sich bei sowas oft nur schwer eine bessere Variante finden...
 
Passende Stellenanzeigen aus deiner Region:

Neue Themen

Oben