2016-08-05 33 views
1

Kürzlich habe ich einen Java-Code von Minen Umstrukturierung versucht, wo immer möglich zu beseitigen static stuff (Variablen und Methoden) und ersetzen Sie es mit besseren Programmierpraktiken.Reflection VS statische Zeug

Ich begann auch Reflexion und bemerkte zu studieren, dass es mir ein paar Dinge , die auf dem ersten zu tun erlaubt, ich nur (oder zumindest das ist, wie ich es sehe) erreichen könnte mit static Anrufen oder Referenzen.

Allerdings, während ich gelesen habe, dass die Verwendung von static nicht viel zu empfehlen ist, scheint es nicht das gleiche mit der Reflexion zu sein.

Also frage ich: statt eine Methode static zu machen und es wie ClassName.methodName() zu nennen, ist es eine legitime Verwendung der Reflexion, die es zu einer Instanzmethode macht und sie durch aufruft?


wie dynamisch eine Klasse Inhalt


Hier ist ein Beispielcode zugreifen:

Hypothetische Situation, die funktioniert (aber ich will nicht um die Methode machen static) :

import static java.lang.System.out; 


public class Foo 
{ 
    private static boolean light; 


    public Foo() 
    { 
     turnOn(); 
    } 

    public static void turnOn() 
    { 
     light = true; 
    } 

    public static void turnOff() 
    { 
     light = false; 
    } 

    public static boolean isGreenLight() 
    { 
     return light; 
    } 
} 

public class Boo 
{ 
    public Boo() 
    { 
     if (Foo.isGreenLight())  // I need to access Foo.isGreenLight() from here, but cur- 
     {        // rently that method is not static (it should be to do so) 
      out.println("Ok!"); 
     } 
    } 
} 

public final class Main 
{ 
    public static void main(String[] args) 
    { 
     final Boo boo = new Boo(); 
    } 
} 

Hypothetische Situation tion, der sollte auch funktionieren (wie es Reflexion verwendet werden würde):

import static java.lang.System.out; 
import java.lang.reflect.Method; 


public class Foo 
{ 
    private boolean light; 


    public Foo() 
    { 
     turnOn(); 
    } 

    public void turnOn() 
    { 
     this.light = true; 
    } 

    public void turnOff() 
    { 
     this.light = false; 
    } 

    public boolean isGreenLight() 
    { 
     return this.light; 
    } 
} 

public class Boo 
{ 
    public Boo() 
    { 
     if ((boolean) Class.forName("Foo").getMethod("isGreenLight", null).invoke(new Foo(), null)) 
     { 
      out.println("Ok!"); 
     } 
    } 
} 

public final class Main 
{ 
    public static void main(String[] args) 
    { 
     final Boo boo = new Boo(); 
    } 
} 

Erwartete Ausgabe (ungetestet):

Ok!

+1

Es geht nicht darum, wie der Aufruf (direkte vs Reflexion) zu machen, sondern über die Änderung der Methode * selbst * als nicht statisch. Wenn Sie den direkten Aufruf einfach als Reflektionsaufruf ändern, die Methode aber als statische Methode belassen, haben Sie den Code * schlechter gemacht !! * – Andreas

+1

Was genau meinen Sie mit "Wert von dieser Methode abrufen"? ? Holen Sie den Wert, den es zurückgibt? Vielleicht sollten Sie einige Codebeispiele geben. –

+0

@Andreas Ja, ich spreche über die Möglichkeit, die Methode zu ändern, um nicht-statische zu sein, und darauf zugreifen von Reflection –

Antwort

4

Die Verwendung von Reflektion ist ein Code-Geruch, vor allem, wenn die Absicht hinter dem, was Sie schreiben, es nicht garantiert.

Es ist schwierig, viel mehr zu sagen, ohne Code zu sehen, da es alles nur Ratespiel ist.

Ich würde:

  • aufzählen, die Gründe, warum Sie in erster Linie jene static Mitglieder hatten

  • bestimmen, ob der static Modifikator in der Tat die richtige Entscheidung in erster Linie war: dh sollten diese Instanzen oder Klassenmitglieder sein? Wie können sie von "Kunden" der betreffenden Klassen verwendet werden? Welches Paradigma benutze ich? Funktionaler oder objektorientierter Code. Entspricht es den Programmierpraktiken DRY, SOLID und KISS?

  • überlegen, ob ich über Engineering in erster Linie bin

Noch wichtiger:

  • ich meinen Code durch Tests entwerfen würde erste, die das Design Ihrer Laufwerke API durch das Auge des Benutzers, mit dem zusätzlichen Vorteil, dass Sie Testabdeckung haben, bevor Sie überhaupt implementiert haben. Oftmals, wenn ich Code auf diese Weise schreibe, eliminiere ich solche Fragen, weil die Lösung offensichtlicher ist, wenn man sie aus der Perspektive eines Benutzers und nicht eines Designers betrachtet. Es wird eine Frage des Pragmatismus, anstatt architektonische Entwurfsziele und -philosophien zu erfüllen.
+0

Ich bin mir nicht sicher, ob Sie den ersten Punkt konstruieren. Ich fühle, dass "statisch" vom OP überstrapaziert wird, aber ich gebe zu, dass es ohne Beispiel schwer zu sagen ist: –

+0

Wie kann man eine Designentscheidung rechtfertigen, indem man zu viel Engineering betreibt? –

+0

Entschuldigung, wenn mein Kommentar mehrdeutig war. Ich meinte, ich war mir fast sicher, dass das kein Über-Engineering ist. Ich habe nur auf Ihren dritten Punkt Bezug genommen. Ich stimme der Antwort wirklich zu. –