2016-12-26 3 views
1

Kürzlich habe ich von der Fabrik und Singleton Design-Muster gelernt und möchte sie zusammen implementieren. Das Problem, das ich habe, ist, dass die in einer Singleton-Klasse definierte Methode getInstance statisch sein muss, also wie kann ich diese Methode in einer Schnittstelle deklarieren? Java 1.8 erlaubt statische Methoden innerhalb von Schnittstellen aber dies besteht darauf, dass eine Methode Körper innerhalb der tatsächlichen Schnittstelle implementiert ist - das zieht sofort von der Wirksamkeit der Verwendung der Singleton mit einer Fabrik.Ist es möglich, eine Singleton-Instanz von einer Fabrik erstellt

Zum Beispiel:

// Logger.java (interface) 
public interface Logger { 

    public Logger getInstance(); 
    public static void log(String message); 

} 

erzeugt einen Fehler, wenn sie umgesetzt werden, wie:

// File implementation of Logger (also a database implementation) 
public class FileLogger implements Logger { 

    private static FileLogger instance; 

    private FileLogger() { 
    } 

    @Override 
    public static Logger getInstance() { 
     synchronized (FileLogger.class) { 
      if (instance == null) { 
       instance = new FileLogger(); 
      } 
     } 
     return instance; 
    } 

    @Override 
    public void log(String message) { 
     System.out.println(new Date() + " " + message); 
    } 

} 

aus einer Fabrik wie:

// Factory pattern to create differing types of logger 
public class LoggerFactory { 

    private LoggerFactory() { 

    } 

    public static Logger getLogger(LoggerType loggerType) { 
     Logger logger; 

     switch (loggerType) { 
      case DATABASE: 
       logger = DatabaseLogger.getInstance(); 
       break; 
      default: 
       logger = FileLogger.getInstance(); 
     } 
     return logger; 
    } 

    public enum LoggerType { 
     DATABASE, FILE; 
    } 
} 

Hoffentlich erklärt meine missliche Lage. Der Fehler, den ich bekomme, ist missing method body

Gibt es Möglichkeiten, dies zu lösen?

+0

Es gibt keine "statische" Schnittstellenmethode. –

+0

Warum benötigen Sie die 'static' Methode an der Schnittstelle? Sie greifen auf statische Methoden über ihren Typ direkt zu, so dass Sie bereits wissen, ob es eine 'getInstance'-Methode gibt. Sie könnten stattdessen die 'getInstance'-Methode als eine' abstrakte' Methode in der 'LoggerType'-Enumeration platzieren, die Ihre switch-Anweisung eliminieren würde. –

+0

Das Entfernen der Definition von der Schnittstelle hat mein Problem vollständig behoben. Ich dachte, Sie könnten nur Methoden implementieren, die in der Schnittstelle definiert sind? Wie auch immer, Prost. – user2228313

Antwort

0

Ich bin mir nicht sicher, ob ich deine Frage vollständig verstehe, aber du könntest so etwas machen, um eine Fabrik zu produzieren, die Singletons produziert.

Was Sie mit einer Fabrik suchen, ist normalerweise eine Instanz einer bestimmten Schnittstelle. Ob es Singleton ist oder nicht, ist aus der Sicht des Aufrufers der Factory-Methode irrelevant. Also würde ich eine Schnittstelle definieren, wie so:

public interface InterestingInterface { 
    public void print(); // my interesting method that I need all 
         // "products to implement" 
} 

Und dann, dass meine Klassen implementiert die Schnittstelle Singletons sein könnte oder nicht, je nach Zweck, so:

public class SingletonA implements InterestingInterface { 

    private static SingletonA instance = null; 

    private SingletonA(){} 

    public static SingletonA getInstance() { 
     if (instance == null) { 
      instance = new SingletonA(); 
     } 

     return instance; 
    } 

    @Override 
    public void print() { 
     System.out.println("I am A"); 
    } 
} 

class SingletonB implements InterestingInterface { 
    private static SingletonB instance = null; 

    private SingletonB(){} 

    public static SingletonB getInstance() { 
     if (instance == null) { 
      instance = new SingletonB(); 
     } 

     return instance; 
    } 

    @Override 
    public void print() { 
     System.out.println("I am B"); 
    } 
} 

public class C implements InterestingInterface { 
    @override 
    public void print() { 
     System.out.println("I am C"); 
    } 
} 

Die Verantwortung der Fabrik ist zu wissen, welche Implementierungsklasse zu instanziieren und wie es zu tun ist. In diesem Fall könnte es so aussehen:

public class SingletonFactory { 
    public static InterestingInterface produce(int id) { 
     switch(id) { 
      case 1: 
       return SingletonA.getInstance(); 
      case 2: 
       return SingletonB.getInstance(); 
      case 3: 
       return new C(); 
      default: 
       return null; 
     } 
    } 
} 

dies mit Ihrem Werk Sie mit der korrekten Implementierung einer Schnittstelle je nach Eingabe bereitstellt (könnte die Art Klasse, die Sie in Ihrer Frage statt Ints verwendet werden) und einig der Implementierungen (oder alle, wenn Sie möchten) können Singletons sein.

Verwandte Themen