2008-09-26 19 views
6

Ich habe gerade eine Klasse namens "InstructionBuilderFactoryMapFactory" erstellt. Das sind 4 "Muster-Suffixe" für eine Klasse. Es sofort erinnerte mich an diese:Zu viele "Muster-Suffixe" - Design-Geruch?

http://www.jroller.com/landers/entry/the_design_pattern_facade_pattern

Ist das ein Design Geruch? Sollte ich diese Nummer begrenzen?

Ich weiß, dass einige Programmierer für andere Dinge ähnliche Regeln (zum Beispiel nicht mehr als N Ebenen der Zeiger indirection in C.)

Alle Klassen scheinen mir notwendig. Ich habe eine (feste) Karte von Strings zu Fabriken - etwas, das ich die ganze Zeit mache. Die Liste wird lang und ich möchte sie aus dem Konstruktor der Klasse entfernen, die die Builder verwendet (die von den Fabriken erstellt werden, die aus der Map stammen ...). Und wie immer vermeide ich Singletons.

+0

Sehen Sie, deshalb hasse ich Java. Sie würden (wahrscheinlich) keine Klasse mit diesem Namen in C++ sehen. – davr

+0

verwenden Sie einen IOC-Container? –

Antwort

4

Ich sehe es als Design-Geruch - es wird mich denken lassen, wenn alle diese Ebenen der Abstraktion genug Gewicht ziehen.

Ich kann nicht sehen, warum Sie eine Klasse 'InstructionBuilderFactoryMapFactory' nennen wollten? Gibt es andere Arten von Fabriken - etwas, das keine InstructionBuilderFactoryMap erstellt? Oder gibt es andere Arten von InstructionBuildersFactories, die zugeordnet werden müssen?

Dies sind die Fragen, an die Sie denken sollten, wenn Sie Klassen wie diese erstellen. Es ist möglich, all diese verschiedenen Fabrikfabriken nur zu einem einzigen zusammenzufassen und dann separate Methoden für die Erstellung von Fabriken bereitzustellen. Es ist auch möglich, diese Fabrik-Fabrik in ein anderes Paket zu legen und ihnen einen prägnanteren Namen zu geben. Denken Sie über alternative Wege nach, dies zu tun.

+1

Die Aufgabe des IBFMF besteht darin, die fixierten String-> IBF-Mappings anzugeben. Da es nur einen IBFM gibt, besteht die Alternative darin, sich in einem Konstruktor zu initialisieren. – finnw

+0

Und ja, es gibt ein paar hundert IBFs – finnw

3

Viele Muster in einem Klassennamen ist definitiv ein Geruch, aber ein Geruch ist kein eindeutiger Indikator. Es ist ein Signal, "für eine Minute anzuhalten und das Design zu überdenken". Viele Male, wenn Sie sich zurücklehnen und denken, dass eine klarere Lösung offensichtlich wird. Manchmal aufgrund der gegebenen Einschränkungen (Technik/Zeit/Mannstärke/etc) bedeutet, dass der Geruch für jetzt ignoriert werden sollte.

Für das konkrete Beispiel, ich glaube nicht, dass Vorschläge aus der Erdnuss-Galerie eine gute Idee ohne mehr Kontext sind.

14

Ein guter Tipp ist: Ihre Klasse öffentliche API (und das enthält den Namen) sollte zeigen Absicht, nicht die Umsetzung. Ich (als Kunde) ist es egal, ob Sie das Builder-Muster oder das Factory-Muster implementiert haben.

Nicht nur der Klassenname sieht schlecht aus, er sagt auch nichts darüber aus, was er tut. Sein Name basiert auf seiner Implementierung und internen Struktur.

Ich verwende selten einen Musternamen in einer Klasse, mit Ausnahme von (manchmal) Fabriken.

Edit:

ein interessantes article Gefunden auf Coding Horror zu nennen, es bitte überprüfen!

+1

Die InstructionBuilderFactoryMapFactory tut was der Name sagt - erstellt eine InstructionBuilderFactoryMap. Der Client hat einen passenden Namen (einfach "Parser") für was * es *. Warum es * will * ein IBFM wird nicht enthüllt, aber es tut & etwas (in diesem Fall die IBFMF) muss es erstellen. – finnw

+1

Ich bin mit Pablo - Muster Namen in Ihren Klassennamen sind ein Informationsleck und Rande gegen Verletzung der Implementierung Privatsphäre. Anstelle von "Factory" verwende ich Begriffe wie "Quelle" oder "Schöpfer", die die Absicht vermitteln, ohne interne Implementierungsdetails preiszugeben. – TMN

0

Ich habe die gleiche Sache gedacht. In meinem Fall wird die Fülle von Fabriken durch "Build for Testability" verursacht. Zum Beispiel habe ich einen Konstruktor wie folgt aus:

ParserBuilderFactoryImpl(ParserFactory psF) { 
... 
} 

Hier habe ich einen Parser - die ultimative Klasse, die ich brauche. Der Parser wird durch Aufruf von Methoden für einen Builder erstellt. Die Builder (neu für jeden Parser, der erstellt werden muss) werden von der Builder-Factory abgerufen.

Nun, was ist die h.l ParserFactory? Ah, ich bin froh, dass du gefragt hast! Um die Implementierung des Parser Builders zu testen, muss ich die Methode aufrufen und dann sehen, welche Art von Parser erstellt wurde. Der einzige Weg, dies zu tun, ohne die Einkapselung der Parser-Klasse zu unterbrechen, die der Builder gerade erstellt, ist, einen Interception-Punkt direkt vor dem Erstellen des Parsers zu setzen, um zu sehen, was in seinen Konstruktor geht. Daher ParserFactory. Es ist nur eine Möglichkeit für mich, in einem Komponententest zu beobachten, was an den Konstruktor eines Parsers übergeben wird.

Ich bin mir nicht ganz sicher, wie ich das lösen soll, aber ich habe das Gefühl, dass wir besser Klassen statt Fabriken passieren und Java würde es besser machen, wenn es richtige Klassenmethoden anstelle von statischen Elementen hätte.