Ist es gut, instanceof oft zu verwenden?

8

Das Szenario. Ich schreibe spielbezogenen Code. In diesem Spiel hat eine Player (auch eine Klasse) eine Liste von Item . Es gibt andere Typen von Elementen, die von Item erben, z. B. ContainerItem , DurableItem oder WeaponItem .

Offensichtlich ist es sehr praktisch für mich, nur List<Item> zu haben. Aber wenn ich die Gegenstände des Spielers erhalte, kann ich nur anhand des instanceof -Schlüssels zwischen den verschiedenen Arten von Gegenständen unterscheiden. Ich bin sicher, ich habe gelesen, dass es eine schlechte Übung ist, sich darauf zu verlassen.

Ist es in Ordnung, es in diesem Fall zu verwenden? Oder sollte ich meine gesamte Struktur überdenken?

    
Bebras 17.06.2015, 14:07
quelle

6 Antworten

10

Nehmen wir an, ich schreibe einen Inventarcode:

%Vor%

Das wird kompilieren und gut funktionieren. Aber es fehlt eine Schlüsselidee des objektorientierten Designs: Sie können übergeordnete Klassen definieren, um allgemeine nützliche Dinge zu tun, und untergeordnete Klassen müssen bestimmte wichtige Details ausfüllen.

Alternativer Ansatz zu oben:

%Vor%

Nun haben wir einen Ort, an dem wir nachschauen können, die show() -Methode, in allen unseren untergeordneten Klassen für die Inventaranzeigelogik. Wie greifen wir darauf zu? Einfach!

%Vor%

Wir behalten die gesamte itemspezifische Logik in spezifischen Item-Unterklassen. Dies macht Ihre Codebasis einfacher zu pflegen und zu erweitern. Es reduziert die kognitive Belastung der langen for-each-Schleife im ersten Codebeispiel. Und es macht show() wieder verwendbar in Orten, die Sie noch nicht einmal entworfen haben.

    
Matt Stephenson 17.06.2015, 14:22
quelle
3

Sie sollten vielleicht überdenken und versuchen, Polymorphismus zu verwenden, um Ihre List<Item> Idee zu implementieren.

Hier sind einige Referenzen für Ihr Problem, die wahrscheinlich helfen können:

(Referenzen aus Instanceof als schlechte Praxis angesehen? Wenn ja, unter welchen Umständen ist instanceof noch vorzuziehen? )

    
Valentin Montmirail 17.06.2015 14:14
quelle
2

IMHO mit instanceof ist ein Code-Geruch. Einfach gesagt - es macht Ihren Code prozedural, nicht objektorientiert. Die OO-Methode hierfür ist das Besuchermuster .

Mit dem Besuchermuster können Sie auch decorator s und chain of responsibility ganz einfach erstellen und so eine Trennung der Probleme erreichen, was zu einem kürzeren, saubereren und leichter zu lesenden und zu testenden Code führt.

Müssen Sie wirklich die genaue Klasse kennen? Kannst du Polymorphismus nicht ausnutzen? Immerhin ist Axe IS ein Weapon , genauso wie Sword ist.

    
Svetlin Zarev 17.06.2015 14:12
quelle
2

Sie sollten Ihre Struktur überdenken, instanceof in Nicht-Meta-Code ist fast immer ein Zeichen für ein Anti-Muster. Versuchen Sie, das Verhalten zu definieren, das alle Item s gemeinsam haben (wie ein Bild, eine Beschreibung und etwas, wenn Sie darauf klicken) in der Item -Klasse / interface, wobei Sie das abstract -Keyword if verwenden appropiate, und dann Polymorphismus , um die Besonderheiten zu implementieren.

    
LionC 17.06.2015 14:11
quelle
0

Es ist in Ordnung, wenn du es leicht verstehst.

Das Verschieben von Verzweigungslogiken, von denen sie natürlich alle zu Unterklassen gehören, ist nicht unbedingt eine gute Idee. Es kann die falsche Abhängigkeit erzeugen; es kann zu aufgeblähten Klassen führen, und es kann schwierig sein, zu navigieren und zu verstehen.

Letztendlich geht es darum, unseren Code mit mehreren Dimensionen von Bedenken in einem eindimensionalen Raum physikalisch zu organisieren. Es ist kein triviales Problem, es ist subjektiv und es gibt kein Allheilmittel.

Insbesondere hat unsere Industrie eine Reihe von Daumenregeln geerbt, die im letzten Jahrhundert auf der Grundlage von technischen und wirtschaftlichen Zwängen dieser Ära gemacht wurden. Zum Beispiel waren die Werkzeuge sehr begrenzt; Programmierer waren sehr teuer; Anwendungen entwickelten sich langsam.

Einige dieser Regeln gelten heute möglicherweise nicht mehr.

    
ZhongYu 17.06.2015 14:41
quelle
0

Ich denke nicht unbedingt, dass instanceof für Programmierer, die wissen, was sie tun, schlecht ist und dass sie es verwenden, um zu vermeiden, dass sie komplizierteren Code schreiben müssen, um das zu umgehen. Es gibt einen Nutzen für alles und auch einen Mißbrauch.

Damit ist die Beschreibung, die Sie angeben, nicht instanceof erforderlich. Es gibt verschiedene Möglichkeiten, dies ohne instanceof zu implementieren, und (die wichtigste Sache) muss die alternative Lösung besser sein als instanceof. Gehen Sie nicht einfach mit einer nicht-instanceof Lösung, um instanceof zu vermeiden, weil Sie gehört haben, dass es schlecht ist.

Ich denke, dass eine Nicht-Instanz einer Lösung für Ihr Szenario Vorteile hat, die Lösung einfacher erweiterbar zu machen.

%Vor%

oder

%Vor%     
Jose Martinez 17.06.2015 14:51
quelle

Tags und Links