2013-04-26 11 views
6

Ich habe eine Util-Klasse, die einige Arbeit ausführen. Offensichtlich ist es für die Erweiterung geschlossen und alle Methoden sind statisch. Aus Gründen der Einfachheit, sieht die Klasse wie folgt:Template Methode Muster für statische Klassen

public final class Util { 
    private Util() { } 

    public static void doWork() { 
     // some work 
     int variable = help(); 
     // some work uses variable 
    } 

    private static int help() { 
     // some helper functionality 
    } 
} 

Die Klassenmethode hat doWork, die eine Menge von Berechnungen durchführt. By the way, Methode ruft Helfer Methode help, um einige Ergebnisse und den Rest des Codes zu erhalten verwenden Sie das Ergebnis von help Methode zurückgegeben.

Nun, im Client-Code möchte ich die Funktionalität der Methode doWork wiederverwenden, aber anstatt help aufrufen möchte ich help2 Methode aufrufen. Die einfachste Lösung ist das Erstellen der Methode doWork2 mit Ersetzen von help bis help2.

Es ist sehr schlechte Ansatz, denn jede Änderung in doWork muss in doWork2 entweder repliziert werden. Dies ist sehr ähnlich zu Template Method Muster, aber aufgrund der Tatsache, dass wir hier keine Erweiterung haben, können wir es nicht anwenden.

beste Lösung, die ich mit dem Parameter hinzufügen, um dieses Verfahren kam, aber erhalte alle bestehenden Nutzer von doWork:

public static void doWork() { 
    doWorkWithParameter(true); 
} 

public static void doWorkWithParameter(boolean helpOrHelp2) { 
    // some work 
    int variable = helpOrHelp2 ? help() : help2(); 
    // some work uses variable 
} 

Was besseren Design-Lösungen angewandt werden können, um dieses Problem zu lösen? Gibt es eine Möglichkeit, Flexibilität wie Template Pattern zu erreichen, aber in Anwendung auf Util-Klassen.

Vielen Dank im Voraus.

+0

Gibt es einen Grund, warum Sie -Methodenüberladung nicht in Ihrer Lösung verwenden? 'public static void doWork() {...}' 'öffentliche statische void doWork (boolean param) {...}' – Crazenezz

+0

Oder besser noch 'public static void doWork (int variable)'. Obwohl ich die tatsächliche Antwort vermute, ist die Verwirrung auf die Statik zurückzuführen und Objekte würden eine sauberere Antwort liefern - schwer zu sagen mit den abstrakten Beispielen. –

+0

Was Sie suchen, ist Strategie-Muster. Prüfe Arnaldos Antwort. –

Antwort

5

Mein Vorschlag in der Command Pattern inspiriert, wo Util-Klasse ist ein Fragesteller und jeweils doWork Hilfepaare sind gekapselt die Worker-Schnittstelle.

Der Arbeiter Inteface einige wie

public interface Worker { 
    public void doWork(); 
    public int help(); 
} 

Die Util Klasse

public final class Util { 
    private Util() { } 

    public static void toWork(Worker worker){ 
     worker.doWork(); 
    } 

} 

Die Betonbauer (Implementierungen von Hilfe und doWork)

public class ConcreteWorker implements Worker{ 

    @Override 
    public void doWork() { 
     // TODO Auto-generated method stub 
      int variable = help(); 

    } 

    @Override 
    public int help() { 
     // TODO Auto-generated method stub 
     return 0; 
    } 

} 

Ein anderer Arbeiter

sein könnte

und die Ausführung

Util.toWork(new ConcreteWorker()); 
Util.toWork(new ConcreteWorker2()); 
+0

Anstelle der Worker-Schnittstelle sollten Sie es besser als eine abstrakte Klasse mit doWork() -Methode machen. Das ist eigentlich das Gleiche wie das, was ich vorschlage, aber nur mit mehr Code. Sie haben vier Klassen statt einer. Ich nehme an, Enums sind ein besserer Ersatz für statische Methoden. – Mikhail

+1

Großartig! Es sieht nach dem Strategiemuster 'Collections.sort (lst, Comparator)' aus. Wie könnte ich das vermissen? – mishadoff

1

Sie könnten erstellen 2 statisches Objekt Help1 & Help2 Implementierung Help Schnittstelle wich eine Hilfe() -Methode und Ihre doWorkWithParameter Methode wie folgt ändern:

public static void doWorkWithParameter(Help h) { 
    int variable = h.help(); 
} 

Es eng ist, um Ihre aktuelle Lösung bezogen. Aber ich denke, es ist ein wenig mehr "objektorientiert".

1

nicht so lange her, habe ich das gemacht:

public static enum Helper{ 
    OLD(){ 
     public int help(){ 
      return 0; 
     } 
    }, 

    NEW(){ 
     public int help(){ 
      return 1; 
     } 
    }; 

    public abstract int help(); 

    public void doWork() { 
     int variable = help(); 
    } 
} 

public static Helper HELPER = Helper.NEW; 

dann können wir nennen:

Constants.HELPER.doWork() 

Durch konstante Werte HELFER Schalt I-Verhalten ändern können. oder Sie tun können:

Helper.OLD.doWork(); 
Helper.NEW.doWork(); 
+0

Danke, schöner Trick. – mishadoff

+0

Dies ist von Effektiven Java-Buch - "Element 34: Emulate erweiterbare Aufzählungen mit Schnittstellen emulieren" – Mikhail