Wo am besten eine String Konstante initialisieren?

Diskutiere Wo am besten eine String Konstante initialisieren? im Java Basics - Anfänger-Themen Bereich.
I

ideot2

Hallo.
Ich habe Klassen B, C, D, E, F und G welche alle von A erben.
Alle Klassen überschreiben eine Methode
Code:
String convert(String input) {
    //code hier
}
Jetzt müssen B und C gebrauch von der selben RegEx machen.

Ich habe also mehrere Möglichkeiten:

1) Ich initialisiere den RegEx String in den überschriebenen Methoden in B und C
2) Ich initialisiere den RegEx String in der Superklasse A als public static Feld.
3) Ich initialisiere den RegEx String in der Superklasse A als private static Feld und biete Zugang über eine getter methode
4) ???

Ehrlich gesagt finde ich alle Möglichkeiten schlecht.
1) verstößt gegen DRY.
2) entblößt den regex im gesamten Code (welcher ziemlich groß ist)
2) und 3) initialisieren außerdem einen String (der reguläre Ausdruck) welcher nicht unbedingt viel mit der Klasse A zu tun hat was ich auch unschön finde.

Was kann ich in diesem Fall noch machen?

Um etwas genauer zu werden, der reguläre Ausdruck dient dazu, den input String auf eine bestimmte Art und Weise zu splitten. Nun habe ich aber zig andere Klassen die von A erben aber keine Verwendung für diesen regulären Ausdruck haben.
 
J

JustNobody

Also so Konstanten mache ich in der Regel immer public static final. Da ist die Sichtbarkeit aus meiner Sich kein wirkliches Problem. Konstanten sind in der Regel ja keine Implementierungsdezails, die zu kapseln sind. (Wobei Reguläre Ausdrücke da ggf. grenzwertig sind, ja)

Wenn du es aber wirklich nur in B und C haben möchtest, dann machst du eine neue Klasse, die von A erbt, in der dann die Konstante ist - von mir aus protected - und davon erben dann B und C.

Die Frage ist aber wirklich, ob eine einzelne Konstante dies so rechtfertigt ...
 
mrBrown

mrBrown

4: Den Regex und möglicherweise zugehörigen Code in eine neue Klasse auslagern, B und C nutzen diese dann.
 
J

JustNobody

Wobei es hier um eine Funktionalität geht. Wenn die anderen Klassen, die von A erben, eine prinzipiell ähnliche Funktionalität haben, dann bietet sich ggf. auch sowas wie das Strategy Pattern an. Also man verschiebt die generelle Verarbeitung der Eingabe in eine Klasse. Das geht aber dann natürlich deutlich weiter was das Design angeht.

Wenn es eine spezielle Verarbeitung ist, dann ist das natürlich auch generell in eine eigenständige Klasse verschiebbar. Da sehe ich dann aber halt das Problem, dass dies dann gerne auf Helferklassen hinaus läuft, die bezüglich OO unschön sind.

Da kommen dann die *Utils *Helper oder Namen wie Strings / Arrays / ... zustande, die sich durch viele static Methoden auszeichnen...

Sowas kann man sich natürlich auch bauen. Und dann hat man die Funktionalität ja gekapselt - der RegEx ist dann ggf. versteckt und du hast die Funktionalität in einer oder mehrerer (ggf static) Methoden ...
 
mrBrown

mrBrown

Generell wäre je nach Problem auch Vorschlag 1 möglich, nur weil etwas gleich aussieht, ist es ja nicht immer auch das selbe. Abkürzungen, Satzenden und Zahlen nutzen alle einen Punkt – trotzdem sollte man sich höllischst davor hüten, eine Konstante PUNKT = "." einzuführen, um nicht gegen DRY zu verstoßen (sowas sieht man btw ständig, wenn Anfänger von DRY, Magic Numbers und Konstanten hören...). Ohne den Kontext zu kennen, kann man das aber nicht wirklich beurteilen.

Was gegen Vorschlag 2 & 3 spricht, steht ja schon im Eröffnungspost, besonders den Punkt, dass A nichts damit zu tun hat, würde ich da als Ausschlaggebend ansehen.


Und als weitere Möglichkeit: man könnte den Regex einfach an die Objekte übergeben, die ihn brauchen, eröffnet dann je nach Nutzung dann auch noch weitere Möglichkeiten, zB kann der dann aus einer Konfig-Datei kommen. Hängt aber auch wieder sehr vom Kontext ab.

Wenn die anderen Klassen, die von A erben, eine prinzipiell ähnliche Funktionalität haben, dann bietet sich ggf. auch sowas wie das Strategy Pattern an. Also man verschiebt die generelle Verarbeitung der Eingabe in eine Klasse. Das geht aber dann natürlich deutlich weiter was das Design angeht.
In Richtung Strategy Pattern gehts ja auch schon, wenn man zB nur Regex und Matchen rauszieht, und das nur in B und C nutzt, gibt dann halt eine XYRegexStrategy. A und alle anderen Klassen sind davon ja nicht betroffen, ist also Designmäßig recht begrenzt.

Da sehe ich dann aber halt das Problem, dass dies dann gerne auf Helferklassen hinaus läuft, die bezüglich OO unschön sind.

Da kommen dann die *Utils *Helper oder Namen wie Strings / Arrays / ... zustande, die sich durch viele static Methoden auszeichnen...
Grundsätzlich stimm ich dir da völlig zu.
Das unschöne daran kann man aber zumindest einschränken, wenn es reines Implementierungsdetail ist und das auch explizit gemacht wird (zwischen 'steht direkt im Methodenbody', 'daraus ausgelagert in eine statische Methode in der selben Klasse' und 'die statische Methode in eine eigene Klasse gezogen' gibts halt "von außen" keinen Unterschied, kann aber "nach innen" durchaus eine Verbesserung sein) – auch wenn sich natürlich meistens trotzdem eine schönere Möglichkeit finden lässt.

Utils-Klassen sieht man gefühlt immer weniger, ein paar sind halt leider durch das Sprachdesign nötig, anders wären manche Sachen nicht praktikabel und sinnvoll nutzbar...Allerdings ist das eine völlig andere Baustelle :D
 
W

White_Fox

nur weil etwas gleich aussieht, ist es ja nicht immer auch das selbe.
Genau...so ist es.

Ohne die exakte Aufgabenstellung zu kennen erinnert mich das aber an etwas, daß ich mal wie folgt gelöst habe.:
Java:
public abstract class MainDefinition{
    
    /**
     *Jede der erbenden Klassen macht eigentlich dasselbe, aber in einer anderen
     *"Geschmacksrichtung". Die "Geschmacksrichtung" wird durch diese Methode definiert.
     */
    protected abstract String getSpecialPhenotypeConstant();
    
    public void doTheSpecialThing(){
        //Tut das was alle machen, ruft dabei aber
        //die Methode getSpecialPhenotypeConstant() auf,
        //sodaß das Ergebnis in spezieller Ausprägung vorliegt.
    }
}

public class SpecialPhenotype extends MainDefinition{
    @Override
    protected abstract String getSpecialPhenotypeConstant(){
        return "Something";
    }
}

public class VerySpecialPhenotype extends MainDefinition{
    @Override
    protected abstract String getSpecialPhenotypeConstant(){
        return "Something else";
    }
}
Ich habe das so gemacht, um Dateien zu speichern. Drei oder mehr verschiedene Dateitypen, wo dann drei- oder mehrmals dasselbe gemacht wird und der einzige Unterschied in der Dateiendung besteht.

Ob die konkrete Aufgabenstellung da irgendwie vergleichbar ist...keine Ahnung. Grundsätzlich klingt mir das Problem auch nach Strategiemuster. Wenn da aber andererseits größerer, komplexer Code dranhängt der umgeschrieben werden müßte, und der nicht schlecht genug ist um ihn so umzukrempeln, dann liefern halt zwei Klassen diesselbe Konstante zurück.
Ob eine Lösung gut ist hängt nicht nur von ihrer Eleganz, sondern auch vom Aufwand ab um sie zu erreichen.
 
Thema: 

Wo am besten eine String Konstante initialisieren?

Passende Stellenanzeigen aus deiner Region:
Anzeige

Neue Themen

Anzeige

Anzeige
Oben