Ich arbeite an einer Legacy-Java-Anwendung, die sich mit "Obst" und "Gemüse" beschäftigt, sagen wir mal, um der Frage willen. Sie werden intern als verschiedene Dinge behandelt, weil sie nicht alle Methoden/Eigenschaften gemeinsam haben, aber viele Dinge sind DONE sehr ähnlich zu beiden.Was ist das richtige Design, um damit umzugehen?
Also, wir haben eine Menge von Methoden doSomethingWithAFruit (Frucht f) und doSomethingWithAVegetable (Veg v), die die ordnungsgemäße Verwendung doOtherStuffWithAFruit (Fruit f)/doOtherStuffWithAVeg (Veg v). Und diese sind sehr ähnlich, außer dass Methoden, die Dinge mit Früchten tun, nur die Methoden nennen, die Dinge mit Früchten tun, und das Gleiche für Gemüse.
Ich möchte dies umgestalten, um die Duplizierung zu reduzieren, aber ich bin mir nicht sicher, was der beste Weg ist, das zu erreichen. Ich habe ein bisschen über Designmuster gelesen, aber ich weiß nicht, ob es mir klarer geworden ist. (Ich kann einige Muster in dem Code erkennen, den ich benutze, aber ich weiß nicht, wann ich ein Muster anwenden sollte, um die Dinge zu verbessern. Vielleicht sollte ich mehr über das Refactoring selbst lesen ...)
Ich war Denken Sie an diese zwei Optionen:
1. Erstellen einer Klasse, die eine Instanz von entweder eine Frucht oder ein Gemüse haben kann und es an die Methoden weitergeben, versuchen, die Duplizierung zu minimieren. Es würde so gehen:
public void doSomething(Plant p) {
// do the stuff that is common, and then...
if (p.hasFruit()) {
doThingWithFruit(p.getFruit());
} else {
doThingWithVegetable(p.getVegetable());
}
}
Diese Dinge ein bisschen besser werden würde, aber ich weiß nicht ... es immer noch falsch anfühlt.
2. Die andere Alternative, die ich dachte, war, eine Schnittstelle in Frucht und Gemüse mit dem Zeug zu setzen, das ihnen gemein ist, und dieses zu verwenden, um es herumzugeben. Ich denke, das ist die sauberere Herangehensweise, obwohl ich instanceof
verwenden und zu Obst/Gemüse umwandeln muss, wenn es Sachen braucht, die für sie spezifisch sind.
Also, was kann ich hier noch tun? Und welche Mängel haben diese Ansätze?
UPDATE: Beachten Sie, dass die Frage ein wenig vereinfacht ist, ich suche nach Möglichkeiten, Dinge mit den "Pflanzen" zu tun, das heißt, Code, der sie meistens "nutzt", anstatt ihnen Dinge zu tun. Having said that, beziehen sich diese ähnliche Methoden, die ich nicht in den „Pflanzen“ Klassen sein können und sie in der Regel ein weiteres Argument haben, wie:
public void createSomethingUsingFruit(Something s, Fruit f);
public void createSomethingUsingVegetable(Something s, Vegetable v);
nämlich diese Methoden haben andere Bedenken neben Obst/Gemüse und aren‘ t wirklich geeignet, um in irgendeiner Obst-/Gemüseklasse zu sein.
UPDATE 2: Die meisten Code in diesem Verfahren lesen nur Zustand von den Obst/Gemüse-Objekten und in der Datenbank in dem entsprechenden Typ, Speicher nach Instanzen anderer Klassen erstellen und so weiter - aus meiner Antwort auf eine Frage in den Kommentaren, die ich denke, dass es wichtig ist.
Was ist, wenn die Pflanze keine Frucht oder ein Gemüse ist? –
Ich denke, Sie haben die richtige Idee, auf eine generische Schnittstelle zuzugehen. Lesen Sie auch über Sammlungen nach. Vielleicht erstellen Sie eine Klasse des Typs Definieren Sie alle Methoden, Objekte, Variablen, die Sie flexibel sein müssen, als dann machen Sie das in Ihrem Haupt/Laufzeit. –
Wenn Sie gemeinsame Funktionen für beide implementieren können (ausgehend von den von Ihnen erwähnten Duplikaten), ist es besser, die abstrakte Klasse zu verwenden, da Sie die Implementierung auf der Klasse selbst durchführen können, was den doppelten Code auf der Unterklasse definitiv reduziert. – Jimmy