Ich habe ziemlich viel Java-Code, den ich überarbeite, um ihn wiederzuverwenden. Das Problem ist, dass es viele Teile gibt, die projektspezifisch sind, so dass am Ende eine höhere Kopplungsstufe zwischen dem Anwendungsprojekt und dem Codebasisprojekt besteht.
Vergleichen Sie die folgenden Situationen, in denen wir eine Klasse verwenden, die die Verwendung abstrakter Methoden implementiert, um die Ressourcen aus der untergeordneten Klasse herauszuholen, und eine, in der wir einfach Instanzvariablen deklarieren.
Abstrakte Methoden:
public abstract class SuperBaseClass {
public abstract int getNumberOne();
public abstract String getStringOne();
public abstract String getStringTwo();
public printStuff() {
Log.i("IntAndTwoStrings", String.format("%i %s and %s",
getNumberOne(), getStringOne(), getStringTwo()));
}
}
public class ReusedAppClass extends SuperBaseClass {
public int getNumberOne() {
return 1;
}
public String getStringOne() {
return "String1";
}
public String getStringTwo() {
return "String2";
}
public ReusedAppClass() {
printStuff();
}
}
Instanzvariablen:
public class SuperBaseClass {
protected int numberOne;
protected String stringOne;
protected String stringTwo;
public printStuff() {
//Possibly throw RuntimeExceptions if the app didnt set these
Log.i("IntAndTwoStrings", String.format("%i %s and %s",
numberOne, stringOne, stringTwo));
}
}
public class ReusedAppClass extends SuperBaseClass {
public ReusedAppClass() {
numberOne = 1;
stringOne = "String1";
stringTwo = "String2";
printStuff();
}
}
Gibt es einen Kompromiss? Ist die Situation mit abstrakten Methoden übertrieben, oder wurden dafür abstrakte Klassen erstellt?
Der abstrakte Klassenansatz zwingt die erweiterte Klasse auch, die Variablen zu "initialisieren", während bei den geschützten Instanzvariablen die Standardeinstellungen leicht verwendet werden können, was zu Verwirrung / Fehlern führen kann, wenn sie nicht erweitert werden.
quelle
Meiner Meinung nach besteht ein besserer Ansatz darin, die Komposition zu verwenden und die Vererbung insgesamt zu vermeiden, wenn nur einige Felder angepasst werden sollen. Sie sagen "um die Ressourcen aus der Kinderklasse herauszuholen", also tun Sie es:
Instanziieren Sie dann MyResources-Objekte in Ihren Klassen und passen Sie sie nach Bedarf an. Wenn Sie weiterhin eine Klassenhierarchie benötigen, können Sie Ihr Ressourcenobjekt in der Basisklasse haben und es in den untergeordneten Klassen erben:
quelle
Wenn alle diese Variablen Eigenschaften der Basisklasse sind und Kinder einheitlich von ihnen abhängen, ist es angemessen, sie in der Basis zu deklarieren. Wenn Sie abstrakte get / setters / accessors hinzufügen, können Kinder die Daten nach Belieben massieren. Dies ist überhaupt kein Overkill und OOP wurde entwickelt, um diese Art von Beziehungen auszudrücken.
Wenn Sie feststellen, dass Sie viel zu viele dieser Daten in die Basisklasse übertragen (oder diese Daten nicht allen Kindern gemeinsam sind), ist es möglicherweise an der Zeit, die Basisklasse für einen größeren Umbau in einen Container umzugestalten andere, spezifischere Basisklassen zur Organisation Ihrer Logik und Ihres Codes. Dies wäre etwas komplexer, würde aber ein saubereres Design ermöglichen und bei guter Benennung leichter zu befolgen sein.
In beiden Fällen müssen Sie zunächst analysieren, was genau Sie wiederverwenden möchten, bevor Sie Änderungen vornehmen. Das Erstellen eines wiederverwendbaren Frameworks aus vorhandenem Code endet an einem ganz anderen Ort als das Reorganisieren von Daten und Vorgängen für diese Daten, beispielsweise zur Wiederverwendung von Modulen.
quelle