Besseres Programmierdesign

Renão

Neues Mitglied
Hallo Leute,

ich hoffe hier im richtigen Bereich zu posten, bin ja noch neu hier ;).

Im Moment sitze ich an einem kleinen Tool, dass einen Text parsen soll, und beim Parsen Details direkt in ein Objekt schreiben soll.

Das Parsen an sich bereitet bisher keine Probleme, dank BufferedReader + StringTokenizer.
Allerdings stehe ich nun vor folgendem Problem:

Der Text ist ungefähr nach folgendem Muster aufgebaut:

Attribut1: Wert1
Attribut2: Wert2
...

Demnach gibt es quasi in jeder Zeile auszulesen a) um welches Attribut es sich handelt und b) natürlich der zugehörige Wert.
Dabei gibt es verschiedene Schreibweisen für die Namen der Attribute. Beispielsweise "attribut1", "att1" etc.. Bislang würde ich das mit einer endlosen If-clause abfangen, aber bei ungefähr 30-40 zu lesende Attribute ist das doch sehr unsauber und unübersichtlich.

Frage 1:
Gibt es eine sinnvolle Alternative zu diesem Problem?

Exemplarisches Code-Beispiel für 2 von x Attributen:
Java:
if((naechstesElement.contains("height"))
                  | (naechstesElement.contains("Height"))){
                    // Groesse //
                    if (tokens.hasMoreElements()){
                        naechstesElement = tokens.nextToken();
                        person.setzeGroesse(naechstesElement);
                    }
                } else if ((naechstesElement.contains("Weight"))
                  | (naechstesElement.contains("weight"))){
                    // Gewicht //
                    if (tokens.hasMoreElements()){
                        naechstesElement = tokens.nextToken();
                        person.setzeGewicht(naechstesElement);
                    }
                  // Hier wuerden dann weitere Attribute folgen //
                }

Vielleicht noch wissenswert:
- Die Attribute kommen in einer gewissen Reihenfolge vor, jedoch in keiner festen.
- Nicht alle Attribute müssen vorkommen.

Frage 2:
Wie oben zu sehen, schreibe ich direkt immer in ein Person-Objekt die Werte der Attribute. Dadurch wird mein Person-Objekt natürlich überflutet von Settern und Gettern, was ich ziemlich unschön finde.
Alternativ habe ich mit gedacht, ggf. die Werte erstmal bis zum Ende des Parsens zu sammeln, bspw. in einer HashMap ("Attributname", Wert) und das dann mit einem einfachen Konstruktor des Person-Objektes zu lösen. Aber vielleicht hat da noch jemand eine bessere Idee?


Danke auf jeden Fall schonmal für jede Antwort!
 

Landei

Top Contributor
Erst einmal kannst du schreiben
Java:
naechstesElement.toLowerCase().contains("height")
was dir die doppelte Prüfung spart.

Das Problem ist, dass du in jedem Zweig eine andere Aktion ausführen willst. In Sprachen mit Closures ist das kein Problem, hier könnte man das höchstens mit einem Interface lösen:

Java:
class Bla {
   private static interface PersonChanger {
      public void change(Person person, Object value);
   }
  
   private Map<String, PersonChanger> map = new HashMap<String, PersonChanger>();

   public Bla() {
       map.put("height", new PersonChanger(){ public void change(Person p, Object value){
          p.setHeight(Integer.parseInt(value.toString()));
       }});
       map.put("weight", new PersonChanger(){ public void change(Person p, Object value){
          p.setWeight(Double.parseDouble(value.toString()));
       }});
       ... u.s.w
   }

   public void method() {
      ...
      while(..) {
         ...
         PersonChanger pc = map.get(naechstesElement);
         if(pc == null) { throw new Exception(); }
         naechstesElement = tokens.nextToken();
         pc.change(person, naechstesElement);
      }
   }
}
 

slawaweis

Bekanntes Mitglied
Der Text ist ungefähr nach folgendem Muster aufgebaut:

Attribut1: Wert1
Attribut2: Wert2
...
das kann man sich auch mit dem PropertyResourceBundle laden, um nicht selber parsen zu müssen.

http://download.oracle.com/docs/cd/E17409_01/javase/6/docs/api/java/util/PropertyResourceBundle.html

Frage 2:
Wie oben zu sehen, schreibe ich direkt immer in ein Person-Objekt die Werte der Attribute. Dadurch wird mein Person-Objekt natürlich überflutet von Settern und Gettern, was ich ziemlich unschön finde.
Alternativ habe ich mit gedacht, ggf. die Werte erstmal bis zum Ende des Parsens zu sammeln, bspw. in einer HashMap ("Attributname", Wert) und das dann mit einem einfachen Konstruktor des Person-Objektes zu lösen. Aber vielleicht hat da noch jemand eine bessere Idee?
wenn man viele einfache Eigenschaften hat, sind viele Getter/Setter nicht das optimale. Besser ist eine dynamische Lösung. Landei hat schon eine mit Interfaces vorgestellt. Ich will noch eine Variante mit Enums bringen.

Java:
public class Person
{
 public static enum Type
 {
  HEIGHT,
  WEIGHT,
  //...
  ;
 }

 protected Map<Type, Object> map = ...;

 public Object getProperty(Type type)
  {
  return map.get(type);
  }

 public void setProperty(Type type, Object value)
  {
  map.put(type, object);
  }

}

beim Reinlesen kann man dann so vorgehen:

Java:
person.setProperty(Enum.valueOf(Person.Type.class, naechstesElement), value);

und so kann man auf die Eigenschaften zugreifen:

Java:
person.getProperty(Person.Type.HEIGHT);

Slawa
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
D besseres Klassenkonzept möglich? Allgemeine Java-Themen 9

Ähnliche Java Themen

Neue Themen


Oben