2016-04-03 12 views
1

Ich arbeite gerade an einer Bibliothek und habe versucht, Teile des Codes durch die Verwendung von Schnittstellen so weit wie möglich zu abstrahieren. Einige Bereiche müssen jedoch Konkretionen zurückgeben, da ich keine andere Möglichkeit sehe, die Daten auf eine saubere Art und Weise zurückzugeben. Zum Beispiel muss ein Bereich von Code ein Schlüssel-Objekt zurück:Entkopplung einer Factory, um benutzerdefinierte Factory-Implementierungen zu ermöglichen

public IKey GenerateKey() { 
    return new Key(param1, param2, param3); 
} 

Meine Lösung gerade dies ist eine Factory-Klasse mit statischen Methoden für die Rückgabe concretions zu erstellen:

public IKey GenerateKey() { 
    return KeyFactory.Get(param1, param2, param3); 
} 

Aber jetzt fühle ich mich wie ich habe eine hohe Kopplung zwischen der Fabrik und der Codebasis, da es in einigen Teilen einige Zeilen gibt, die Objekte von der Fabrik anfordern. Es fühlt sich auch einfach faul an, da ich eine Fabrikfunktion aufrütteln kann, um mir in vielen Situationen eine konkrete Klasse zu geben.

Mein größtes Problem besteht darin, Menschen zu erlauben, Klassen zu ersetzen, indem sie ihre eigenen Klassen schaffen, die gegenwärtige Schnittstellen implementieren. Ich muss Benutzern erlauben, ihre eigenen Fabriken für ihre Klassenimplementierungen zu erstellen. Wenn ich eine Schnittstelle für meine Fabrik mache und Benutzern erlaube, ihre eigene Fabrik zu gründen, die die Schnittstelle einführt, dann benötige ich eine höhere Fabrik, um DIESE Fabrik herzustellen, und so weiter ...

Ich brauche Benutzer, um fähig zu sein um ihre eigenen benutzerdefinierten Klassen zu erstellen, die die richtigen Schnittstellen implementieren, erstellen Sie ihre eigene Factory, die ihre benutzerdefinierte Klasse an anderen Stellen des Codes zurückgeben kann, wo sie benötigt werden, und alles um nahtlos zusammenzuarbeiten.

Bearbeiten: Dies ist die Idee, die ich derzeit habe, aber die Fabrik zu injizieren scheint wie eine unkonventionelle Sache zu tun, wenn Sie eine Bibliothek in Java verwenden.

public class Key implements IKey { 
    public Key(param1) { 
     //do something 
    } 
    //other methods 
} 

public interface IKey{ 
    //Other methods 
} 

public class RicksFactory { 
    public IKey getKey(param1) { 
     return new Key(param1); 
    } 
} 

public interface IFactory { 
    IKey getKey(param1); 
} 

//This class is a singleton, for other classes in 
//library to find it without having to do dependency 
//injection down all the levels of classes. 
public class TopClassInLibrary { 
    //Singleton init 

    public void SetFactory(IFactory factory) { 
     this.factory = factory; 
    } 

    public IFactory GetFactory() { 
     return new RicksFactory(); 
    } 
} 

public class Main { 
    public static void main(String[] args) { 
     TopClassInLibrary.GetInstance().SetFactory(new RicksFactory()); 

    } 
} 

** Edit 2: ** Ich glaube, ich habe jetzt eine schöne Lösung herausgefunden, würde es schätzen, wenn mir jemand sagen könnte, wenn sein gut oder nicht? Dank

public class Key implements IKey { 
    public Key(param1) { 
     //do something 
    } 
    //other methods 
} 

public interface IKey{ 
    //Other methods 
} 

public class RicksFactory { 
    public IKey getKey(param1) { 
     return new Key(param1); 
    } 
} 

public interface IFactory { 
    IKey getKey(param1); 
} 

public class TopClassInLibrary { 
    private static TopClassInLibrary topClass; 
    private static TopClassInLibrary GetInstance() { 
     if(topClass == null) 
      topClass = new TopClassInLibrary(); 
     return topClass; 
    } 

    private IFactory factory; 

    public void SetFactory(IFactory factory) { 
     this.factory = factory; 
    } 

    public IFactory GetFactory() { 
     if(factory == null) 
      factory = new RicksFactory(); 
     return factory; 
    } 
} 

public class Main { 
    public static void main(String[] args) { 
     //Below not needed now for default implementation 
     //TopClassInLibrary.GetInstance().SetFactory(new RicksFactory()); 
     IKey myKey = TopClassInLibrary.GetFactory().getKey(param1); 
    } 
} 

So in dieser Konfiguration muss TopClassInLibrary nie die Bibliothek von außen Code instanziiert oder berührt zu verwenden, da es eine eigene Instanz erstellt, wenn gewünscht, und erstellt die Standard-Werk, wenn eine benutzerdefinierte hat eine nicht gesetzt .

+0

Warum ist das Spritzen einer Fabrik unkonventionell? Mit dem Spring Framework kann man so etwas machen. Bei der Verwendung von OSGI/Eclipse verwenden wir Contributors für einen Erweiterungspunkt, um die Registrierung einer Factory zu ermöglichen, was ein ähnliches Konzept ist. – KevinO

+0

Vielleicht habe ich dann nicht genügend Bibliotheken ausgesetzt, es ist nur meiner Erfahrung nach, dass ich noch nie eine eingebaute Fabrik injizieren musste, um eine Bibliothek zu benutzen. – Tom

Antwort

Verwandte Themen