Klassen Fabrik (Factory) zur Laufzeit erweitern

The_Unknown

Mitglied
Hallo,

ich habe mir aus Erweiterbarkeitsgründen eine Factory gebaut, die mir "Events" (eigene Klasse) erstellt:
Java:
public static Event getEvent(String eventType) {
		if (eventType.equals(CONCRETEEVENT)) {
			return new ConcreteEvent();
		
                } // ...
                  else {
			return null;
		}
	}

Nun würde ich gerne diese Factory zur Laufzeit mit neuen konkreten Events erweitern, also Klassen, die von Event erben.

Prinzipiell wäre das kein Problem, nur wie drücke ich das Instantiieren im Quellcode aus? Ich denke an so etwas, wie "... = new StringToClass("ConcreteEvent2");". Geht so etwas?

Ciao The_Unknown
 
[c]Class.forName("der.Name.deiner.Klasse.MIT.packages").newInstance()[/c]
Reflection ist das Stichwort. Obiger Code funktioniert übrigens nur, wenn die Klasse einen Standardkonstruktor implementiert. Existiert dieser nicht, musst du dir per Reflection einen passenden Konstruktor suchen und diesen mit den benötigten Parametern aufrufen.
 
Du koenntest auch nen Prototype Pattern benutzen:

Java:
public abstract class Event {
   public abstract String getType();
   public abstract Event createNew();
}

public class ConcreteEvent extends Event {
   @Override
   public String getType() { return "CONCRETE"; }
   @Override
   public Event createNew() {
      return new ConcreteEvent(); // mit welchen Parametern auch immer
   }
}

public class EventFactory {
   private HashMap<String, Event> events = new HashMap<>();
   public void registerEvent( Event event ) {
      events.put( event.getType(), event );
   }
   public Event getEvent( String type ) {
      return events.get(type).createNew();
   }
}
 
[c]Class.forName("der.Name.deiner.Klasse.MIT.packages").newInstance()[/c]
Reflection ist das Stichwort. Obiger Code funktioniert übrigens nur, wenn die Klasse einen Standardkonstruktor implementiert. Existiert dieser nicht, musst du dir per Reflection einen passenden Konstruktor suchen und diesen mit den benötigten Parametern aufrufen.
Danke euch beiden! Ich habe deinen Ansatz ausprobiert und es funktioniert sehr gut!

Ein Problem gibt es noch: Für eine bestimmte Funktion (XStream-Serialisierung) benötige ich den Ausdruck "KonkreteKlasse.class". Ich habe es auf 2 Weisen versucht:

Java:
Class.forName(currentAvailableEvent).getClass()

Class.forName(currentAvailableEvent)

Leider gibt es nicht

Java:
Class.forName(currentAvailableEvent).class

Wie mache ich das genau?
 
[c]Class.forName(String)[/c] liefert dir bereits ein Class-Objekt zurück, daher ist der Aufruf von getClass unnötig bzw. unsinnig.
Java:
Class.forName("java.lang.String") -> Objekt vom Typ "Class<String>"
 

Zurück
Oben