Ich habe eine JAVA-Klasse A, die eine Methode foo
hat %Vor%Ich habe auch eine abgeleitete Klasse von A - MutableA. MutableA ist ein Singleton-Objekt, das angibt, dass keine Aktualisierung erforderlich ist, die für die Wiederverwendung von Code-Flows nützlich ist. foo () sollte nie auf MutableA aufgerufen werden. Was ist der beste Weg, um das zu erreichen:
Kann mir jemand empfehlen, was in diesem Fall die beste Vorgehensweise ist?
Ich würde überdenken, das Design zu überdenken.
Wenn eine abstrakte Methode in der Superklasse verwendet wird, bedeutet dies, dass Unterklassen diese Methode implementieren sollten. Sofern Sie keine größere Hierarchie planen, sollten Sie in Erwägung ziehen, die foo-Methode in der Hierarchie näher an die Implementierung zu verschieben.
Wenn Sie beabsichtigen, den Standort der foo-Methode beizubehalten, würde ich auch MutableA abstrakt machen.
Sie sollten sich das Liskov-Substitutionsprinzip ansehen, das eines der grundlegenden SOLID-Prinzipien für gutes Design ist.
Das Prinzip besagt, dass sich abgeleitete Objekte nicht anders verhalten sollten als ihre Eltern. Ein gängiges Beispiel für eine Verletzung des Liskov-Prinzips ist die Ableitung eines Kreises aus einer Ellipse. Was mathematisch völlig sinnvoll ist und Klang als schlechtes Design gilt, denn ein aus einer Ellipse abgeleiteter Kreis würde (zum Beispiel) immer noch die Methoden zur Einstellung der Breite und Höhe offenlegen, würde sich aber in manchen Kontexten merkwürdig verhalten. Berücksichtigen Sie Folgendes:
%Vor%Wenn wir nicht wissen, dass ein Aufrufer einen Kreis statt einer Ellipse passiert hat und wir sowohl die Breite als auch die Höhe festgelegt haben, können unsere Ergebnisse von unseren Erwartungen abweichen, da der Kreis entweder SetHeight ignoriert oder den Breiten-Bot auf SetWidth setzt und SetHeight. Wie auch immer, dieses Verhalten ist unerwartet, wenn wir erwarten, auf einer Ellipse zu operieren. Daher das Liskov-Substitutionsprinzip.
Da Sie "no update is needed not necessary" sagen, scheint es, als wäre eine leere Implementierung der richtige Weg. Was mache ich:
%Vor% Ich würde nicht wissen, ob ich ein MutableA
zurückbekommen habe oder nicht, also rufe ich foo
an, nur um sicher zu gehen.
Wenn verboten ist foo
auf einem MutableA
aufzurufen, würde ich mit UnsupportedOperationException
gehen oder das Design überdenken. Vielleicht könnten Sie A
in eine AHandler
umbrechen, die weiß, wann und wie foo
für die umbrochene Instanz aufgerufen wird.
Es kommt darauf an, für welche Methode die Methode gedacht ist. Alle Alternativen, die Sie aufgelistet haben, sind praktisch gut.
Übrigens, wenn Sie eine UnsupportedOperation
Ausnahme auslösen, sagen Sie, dass diese Methode nicht verwendet werden soll. Das Verwenden einer Ausnahme ist immer eine "Nachricht" einer Abweichung von der "normalen", also definieren Sie etwas mit der Basisimplementierung von A.foo()
, aber Sie brechen diese Implementierung auch mit der Unterklasse auf.
Wenn Sie eine leere Implementierung verwenden, machen Sie die Unterklasse innerhalb eines hypothetischen Flusses brauchbarer, ohne mit der Vergangenheit aufzubrechen (die Superklasse A
), so dass Sie in keinem Kontext über die Verwendung von Unterklassen Bescheid wissen will.
In der abschließenden Analyse haben Sie gesagt, dass MutableA
Singleton ist, also denke ich, dass Sie es in einem bestimmten Kontext mit einem bestimmten Blick darauf verwenden werden: Ich würde also die "Ausnahme" -Lösung übernehmen.
Ich würde so etwas verwenden:
%Vor% Überall in Ihrem Code, wo Sie A
erhalten möchten, verwenden Sie stattdessen ReadableA
, es sei denn, Sie möchten ausdrücklich foo()
aufrufen. Fügen Sie dann A
in Ihre Methodensignatur ein. Wenn Sie eine MutableA
erhalten möchten, schreiben Sie eine MutableA
Signatur.
Beispiele:
%Vor% Ich denke, dass das Werfen von UnsupportedOperationException
hier die richtige Wahl ist. Angenommen, Sie erweitern die Klasse A
um 3 Klassen.
Nun sollte sich X,Y,Z and MutableA
in einer Design-Perspektive in einer konsistenten Weise verhalten, in Bezug auf foo()
. Ich würde es abraten, eine andere Klassenhierarchie einzuführen, um MutableA fofree zu machen. Eine einfache Lösung wäre ein UnsupportedOperationException
und der Aufrufer würde wissen, dass die Methode nicht vom aufrufenden Objekt unterstützt werden kann. Eine leere Implementierung andererseits ist immer noch gültig und passt ehrlich gesagt nicht gut in Design-Perspektive , weil sie noch ist ein gültiger Aufruf vom aufrufenden Objekt .
PS: Ich würde auch das Umdenken des Designs in Erwägung ziehen. Jede Methode, die verfügbar ist, aber nicht verwendet werden sollte, ist nicht Teil eines guten Designs.
Tags und Links java inheritance object-oriented-analysis