Neue Instanz/Kopie einer unbekannten Klasse

mabuhay

Bekanntes Mitglied
Hallo

Ich hoffe der Titel ist wenigstens ein bisschen aussagekräftig :p
Also, ich habe folgende Situation:
Ich habe eine Server/Client Bibliothek. Der Server kann mehrere Verbindungen entgegennehmen und ankommende Daten verarbeiten. Jede Verbindung beinhaltet einen Incoming- und einen Outgoing-Processor wo die Daten verarbeitet/aufbereitet werden.

Für den Incoming- und Outgoing-Processor hab ich nun eine Abstrakte Klasse welche einige benötigte Methoden implementiert und auch einige abstrakte Methoden. Also z.B.:
Java:
public abstract class IncomingProcessor {
 public abstract read(InputStream in);
 public byte[] objectToByteArray(Object o) {
  ...
 }
}
Ich will nun die Möglichkeit haben, eine eigene Klasse zu erstellen (welche IncomingProcessor erweitert) und somit das Lesen der Daten mit der read()-Methode individuell zu gestalten.

Mein Problem ist nun, dass im Server bei jeder eingehenden Verbindung eine neue Instanz meiner individuell erstellten Klasse (welche IncomingProcessor erweitert) erstellt werden muss, da zum Beispiel die Information der Verbindung sich jedes mal ändert oder der IncomingProcessor auf Daten warten muss und die anderen Verbindungen nicht Blockieren sollte.

Dazu hab ich mir schon ein wenig das zeugs mit ClassLoader angeschaut. Ich kenn mich da nicht aus, aber es sieht so aus wie wenn dies ziehmlich kompliziert werden könnte.
Ein weiterer Ansatz ist irgendwie sowas:
Java:
Class<? extends IncomingProcessor> c = incoming.getClass();
IndividualIncomingProcessor in = c.newInstance();
Aber da meine Bibliothek ja nur die Abstrakte Klasse IncomingProcessor kennt und nicht die welche ich individuell erstellt habe gibt es da eine InstantiationException.


Kann mir jemand weiterhelfen oder hat Tipps? Sollte ich es am besten mit ClassLoader machen?

mfg
 

mfernau

Bekanntes Mitglied
Ich bin mir nicht sicher ob ich Deine Frage richtig verstanden habe. Es geht hier also um ein komplettes Projekt welches Du selbst entwickelst - ja? Also die ganze API (und damit auch der Teil wo ein Objekt von einer Klasse, welche IncomingProcessor erweitert, erstellt werden soll) liegt in Deinen Händen.
Wenn dem so ist, dann wäre wohl eine Factory der richtige Ansatz. Du musst also Deiner Server-API eine Factory zur Verfügung stellen, die genau die Objekte erstellt die es benötigt und die Du dort haben willst.
Eine Factory ist also eine Schnittstelle die durch deine Server-API zur Verfügung gestellt werden muss. Dort gibt es eine Methode "createIncomingProcessor", welche ein Objekt vom Typ IncomingProcessor zurück liefert:
Java:
interface IncomingProcessorFactory {
   public IncomingProcessor createIncomingProcessor();
}

Nun musst Du eine Implementation dieses Interfaces schreiben, in der Du mit dieser Methode Dein bestimmtes Objekt erzeugst, welches IncomingProcessor ableitet:
Java:
class IncomingProcessorFactoryImple implements IncomingProcessorFactory {
   public IncomingProcessor createIncomingProcessor() {
      // schlaue Sachen...
      return ...
   }
}

Deine Server-API muss Dir die Möglichkeit bieten irgendwie ein Objekt vom Typ IncomingProcessorFactory zu setzen, welches Dein Server dann dazu verwendet Objekte vom Typ IncomingProcessor zu erzeugen. Dadurch muss Dein Server nicht wissen welche Objekte tatsächlich dahinter stecken, sondern benutzt einfach Deine Factory-Klasse welche das tut, was Du möchtest.

Schau Dir dazu mal das "Factory Method Pattern" an.

HTH,
Martin
 

mabuhay

Bekanntes Mitglied
Hallo

Ja ich denke du hast es richtig verstanden ;)

Also sozusagen dass die individuell erstellte Klasse (welche IncomingProcessor erweitert) eine neue Instanz von sich erstellt und zurück gibt, z.B. einfach:

Java:
public abstract class IncomingProcessorFactory {
   protected String verbindungsinfo = null;
   public abstract IncomingProcessor createIncomingProcessor();
}
Java:
class IncomingProcessorFactoryImple implements IncomingProcessorFactory {

   public IncomingProcessor createIncomingProcessor(String verbindungsinfo) {
      IncomingProcessorFactoryImple ipf = new IncomingProcessorFactoryImple();
      ipf.verbindungsinfo = verbindungsinfo;
      return ipf;
   }

}

Seh ich das richtig? werde damit mal ein wenig experimentieren...

mfg
 

mfernau

Bekanntes Mitglied
Naja - eigentlich ist die Factory-Klasse nochmal eine eigenständige Klasse.

Für den Factory-Ansatz brauchst Du zwei neue Dinge.
1. Das Interface (in diesem Zusammenhang besser als eine abstrakte Klasse) mit dieser einen Methode
2. Eine implementierende Klasse

Dann erzeugst Du ein Objekt von der implementierenden Klasse. Dieses Objekt übergibst Du Deinem Server. Dein Server benutzt das Objekt um nach bedarf neue Instanzen von IncomingProcessor zu erzeugen.

Dein Ansatz würde zwar ebenfalls funktionieren - macht die Sache aber nicht ganz logisch. Denn Du brauchst in Deinem Fall ja schon eine Instanz von einer Klasse die IncomingProcessor erweitert hat um wiederum neue Instanzen seiner selbst zu erzeugen. Das ist nicht ganz der Sinn dahinter. Auch wenn das Ergebnis dasselbe wäre - das Factory-Pattern sieht das etwas anders vor :)

Schau mal hier: Factory Method Pattern in Java (oder googel nach Factory Method Pattern)
 

mabuhay

Bekanntes Mitglied
Vielen Dank schonmal für deine Antworten. Ich komm da aber an einem Punkt nicht weiter:

Der Server und Client sind in einer Bibliothek. Ich mache nun in einem neuen Projekt eine Klasse A welche IncomingProcessorFactory erweitert, damit ich die read-Methode etc selber definieren kann.
Diese Klasse A muss ich ja jetzt irgendwie dem Server übergeben, dass der dann nach bedarf neue Instanzen erstellen kann. Du schreibst ja auch "Dieses Objekt übergibst Du Deinem Server", aber um das Objekt zu übergeben muss ich ja schon mal eine Instanz erzeugen oder?
Also z.B. mal als ganz einfaches Beispiel:

Dies ist in der Server/Client Bibliothek:
Java:
public abstract class IncomingProcessorFactory {
   public abstract IncomingProcessor createIncomingProcessor();
}

Im neuen Projekt erstelle ich eine Klasse, von welcher ich will dass der Server sie verwendet:
Java:
class A implements IncomingProcessorFactory {
 
   public A createIncomingProcessor() {
      A newA = new A();
      return newA;
   }

   public void read() {
      //...
   }
 
}

Der Server ruft nun bei jeder neuen Verbindung createIncomingProcessor() auf. Damit der Server aber überhaupt die Klasse des neuen Projekts verwenden kann muss dem Server ja newA übergeben werden:
Java:
public class Server {
    IncomingProcessorFactory ipf = null;
    public Server(IncomingProcessorFactory ipf) {
        this.ipf = ipf
    }

    public void run() {
        //...
        
        //Neue Verbindung
        IncomingProcessorFactory newIncoming = ipf.createIncomingProcessor();
    }
}

Also muss ich dort wo ich den Server erstelle, eine Instanz der Klasse A erstellen um die dann dem Server zu übergeben:
Java:
public void main() {
    A newA = new A();
    Server s = new Server(newA);
}

Ich verstehe dass ich dann die Klasse newA in der main-Methode habe, diese aber nicht verwenden kann/sollte da davon ja sowieso bei jeder Verbindung neue Instanzen erstellt werden.

Ich habe noch versucht die createIncomingProcessor()-Methode static zu machen, bei der BorderFactory zum Beispiel ist es ja auch so, aber dann bräuchte mein Server ja auch irgendwie den Klassennamen, und ausserdem geht static nicht in einem Interface...

Nun weiss ich nicht genau was ich falsch verstehe/sehe. Ich hab schon ein wenig recherchiert, aber hat mir noch keine Klarheit verschafft :p

mfg
 
S

SlaterB

Gast
> A newA = new A();

schreibt man normalerweise nicht, wenn die Klasse A bekannt wäre bräuchte man überhaupt keine Factory,
(edit: siehe auch dein Titel: unbekannte Klasse)
und dass die Klasse sich selber erzeugt ist auch nicht gerade guter Stil, eine AutoFabrik erstellt ja auch Autos, nicht wieder AutoFabriken

das Objekt der Factory-Klasse kommt normalerweise von irgendwo anders her, z.B. hattest du am Anfang InputStream, objectToByteArray() usw.,
eine Alternative ist
> Class.forName(String klassenname).newInstance()

dieses Factory-Objekt einer eher unbekannten Factory-Klasse auf das (bekannte!) Factory-Interface casten, dann kann die Factory-Methode verwendet werden
 
Zuletzt bearbeitet von einem Moderator:

mfernau

Bekanntes Mitglied
Erstmal vorne weg:
1. Du verwechselst abstrakte Klassen mit Interfaces. Seit wann kann man abstrakte Klassen "implementieren"? Du tust es aber in deinem Zweiten Codeschnipsel.
2. Verwende für das Factory-Pattern Interfaces als Factory-Grundlage und implementiere diese dann in Deiner implementierenden Klasse.

So - und nun sehe ich, dass Du definitiv noch Verständnisprobleme bei diesem Thema hast. Ich hole nochmal aus:

Was Du schon mal richtig verstanden hast ist, dass Dein Server eine Instanz der Factory braucht.
Um mal kurz eine Übersicht zu erzeugen, welche Klassen/Interfaces wo liegen:
Package Server:
- Klasse Server (von Dir angegeben)
- Abstrakte Klasse IncomingProcessor
- Interface IncomingProcessorFactory (Für das Factory-Pattern)

So sieht das Interface IncomingProcessorFactory aus:
Java:
public interface IncomingProcessorFactory {
   public IncomingProcessor createIncomingProcessor();
}

Und so sieht Deine abstrakte Klasse IncomingProcessor aus (vom ersten Post von Dir)
Java:
public abstract class IncomingProcessor {
 public abstract read(InputStream in);
 public byte[] objectToByteArray(Object o) {
  ...
 }
}

So, wenn ich Dich nun richtig verstanden habe, dann erstellst Du Dir nun ein neues Projekt in Deiner IDE, welche Deine Server-Bibliothek verwendet. Das ist schon mal gut.
Eine Übersicht deines neuen Projekts:
- Klasse MeinIncomingProcessor
- Klasse MeinIncomingProcessorFactory

Sehen wir uns die Klassen mal im einzelnen grob an. Hier MeinIncomingProcessor:
Java:
public class MeinIncomingProcessor extends IncomingProcessor {
   public void read(InputStream in) {
      // muss implementiert werden, da sie abstrakt in Deiner Server-Bib ist
      // schlaue Sachen... 
   }
   // evtl andere Dinge ...
}

Und Dein Server soll für die Verbindung ja eine Instanz von MeinIncomingProcessor verwenden um den eingehenden Datenstrom zu verarbeiten. Eingangs war Deine Frage, wie Du dem Server klar machen sollst, dass er nun für eingehende Verbindungen eine Instanz von MeinIncomingProcessor erzeugen soll. Was ein Glück - wir benutzen ja hier das Factory-Pattern ;-) Der Server muss gar nicht wissen was er instantiieren soll - Du erledigst das für ihn. Nämlich mit der MeinIncomingProcessorFactory:

Java:
public class MeinIncomingProcessorFactory implements IncomingProcessorFactory {
   public IncomingProcessor createIncomingProcessor() {
      IncomingProcessor meinProcessor = new MeinIncomingProcessor();
      return meinProcessor;
   }
}

Dem Server übergibst Du nun einfach eine Instanz dieser MeinIncomingProcessorFactory:
Java:
MeinIncomingProcessorFactory factory = new MeinIncomingProcessorFactory();
Server s = new Server(factory);

Jedes mal wenn Dein Server eine Instanz von IncomingProcessor benötigt, wird er die Factory-Methode createIncomingProcessor() benutzen. Und weil Du diese Factory in Deinem Projekt so geschrieben hast, wird sie ein Objekt vom Typ MeinIncomingProcessor liefern. Was der Server nicht weiss und auch nicht wissen muss. Denn ihm reicht es ja dass er weiss, dass es ein IncomingProcessor ist.

Das Factory-Design-Pattern bietet Dir die Möglichkeit Deinem Server einen Objekt-Generator in die Hand zu geben, der die Art von Objekte erzeugt, die er für seine Aufgabe benötigt. Ohne das der Server selbst weiss aus welchen konkreten Klassen er Objekte instantiieren soll, bekommt er durch deine FactoryImplementierung für seinen Bedarf das richtige Objekt.
Die Klasse MeinIncomingProcessorFactory könnte in einem dritten Projekt von Dir z.B. anders aussehen und andere IncomingProcessor Objekte liefern. Dafür musst Du den Server aber nicht umschreiben. Dieser bedient sich einfach der Schablonen-Technik des Factory-Design-Patterns und bekommt das Objekt, welches Du für seine Zwecke als richtig erachtest.
 
Zuletzt bearbeitet:

mabuhay

Bekanntes Mitglied
Viiiielen Dank SlaterB und vorallem mfernau für die ausführliche Beschreibung :toll:
Jetzt wird zwar auch eine Instanz der Factory erstellt und muss dem Server übergeben werden, aber die hat ja nur die createXYZ-Klasse und kann somit nicht zu verwirrung führen, wie ich das vorher befürchtet habe :p

@SlaterB: Ja stimmt, die ProcessFactory muss natürlich ein Prozess-Objekt zurückgeben, analog zur Autofarbrik welche Autos produziert.

Und sorry für das interface/abstrakt durcheinander, kam vom Copy-Paste.

mfg und Danke nochmals, wieder was nützliches gelernt ;)
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
S Neue Instanz eines Objekts erzeugen - Konstruktor erhaelt Parameter. Allgemeine Java-Themen 5
N neue Objektnamen durchlaufen Allgemeine Java-Themen 12
C Java11+ JavaFX HtmlEditor ContextMenu neue MenuItems hinzufügen Allgemeine Java-Themen 5
N Apache POI/ neue Reihe in Excel mit einem Button Allgemeine Java-Themen 2
B Java Mail: Prüfung auf neue Emails Allgemeine Java-Themen 1
ralfb1105 Blöcke aus Datei filtern/suchen und in neue Datei schreiben Allgemeine Java-Themen 10
G Excel Tabelle lesen und in neue Excel Tabelle einfügen Allgemeine Java-Themen 11
E neue Lizenzpflicht Java Allgemeine Java-Themen 10
T ändern neue Java Versionen was an der Programmiersprache? Allgemeine Java-Themen 15
K Mit Button neue Klasse öffnen Allgemeine Java-Themen 9
C Classpath Neue Klasse über einen Button ausführen Allgemeine Java-Themen 3
KeVoZ_ Nacheinander folgende Strings in Textdokument auf neue Zeile schreiben Allgemeine Java-Themen 6
J Java Software Compare Files und Neue File erstellen Allgemeine Java-Themen 0
K Einfaches Array in 2 neue aufteilen. Allgemeine Java-Themen 2
N Neue Software in Java 7 oder 8? Allgemeine Java-Themen 3
K Neue Elemente in JList einfügen Allgemeine Java-Themen 2
K Methode soll neue Buttons erstellen Allgemeine Java-Themen 5
S Best Practice verschiedene Exceptions fangen und neue Exception erzeugen Allgemeine Java-Themen 11
W Vergleich eines Datenträgers auf neue Dateien Allgemeine Java-Themen 14
N Datenstrukturen an neue Klasse übergeben Allgemeine Java-Themen 16
F Wie zur Laufzeit ganz neue Objekte erzeugen? Allgemeine Java-Themen 5
J Neue Wörter bilden Allgemeine Java-Themen 10
J Was ist schneller? Neue Variable oder neuer Wert speziell int Allgemeine Java-Themen 3
T Log4J: Bei Programmstart immer eine neue LogDatei erzeugen Allgemeine Java-Themen 9
J Text einer .csv Datei einlesen und Zeile in NEUE Zeile hänge Allgemeine Java-Themen 1
B Logs - txt-Datei neue Zeile anfuegen, neue Datei erstellen Allgemeine Java-Themen 6
S Zweidimensionales Array neue Zeile erzeugen Allgemeine Java-Themen 3
P Neue Zeile Plattformunabhängig Allgemeine Java-Themen 3
W Programm prüft auf webserver ob neue version vorhanden? Allgemeine Java-Themen 3
I Neue Klassenbibliothek in Klassenpfad einbinden Allgemeine Java-Themen 3
B Ausgabe auf stdout "löschen" und dafür neue Ausgab Allgemeine Java-Themen 10
M neue Thread in neuem Fenster Allgemeine Java-Themen 3
M neue Textdatei DOS/Unix-Format Allgemeine Java-Themen 11
WMaerz Der neue JDK 6 enthält keine javac.exe, tool.jar usw. Allgemeine Java-Themen 6
J Neue Objekte werden nciht angezeigt Allgemeine Java-Themen 2
T iText + neue Seite Allgemeine Java-Themen 14
A Kann keine neue Klasse erstellen. Allgemeine Java-Themen 3
G Programm erzeugt ständig neue Strings . Allgemeine Java-Themen 2
G Neue Warenwirtschaft aber sehr langsam! Allgemeine Java-Themen 3
M in jar eine neue datei per JarOutputStream hinzufügen Allgemeine Java-Themen 2
B Braucht man die neue VM 1.5 Allgemeine Java-Themen 3
F neue klassen einbinden Allgemeine Java-Themen 3
F Neue Bibliothek dem JDK hinzufügen Allgemeine Java-Themen 5
EinNickname9 Best Practice Singleton und Singleton mit Instanz zu anderer Klasse -Pattern Allgemeine Java-Themen 30
J Verständnis Frage zur Instanz, Objekte, Instanzierung, Referenz Allgemeine Java-Themen 14
Thallius HTTPS Request mit unbekannter Instanz Allgemeine Java-Themen 24
S Speicherverwaltung bei Instanz- und Klassenvariablen JS vs. Java Allgemeine Java-Themen 2
T MEthodenauruf testen, wenn instanz erst erzeugt wird Allgemeine Java-Themen 0
OnDemand InetAddress Instanz Allgemeine Java-Themen 4
T Klassen Instanz einer Klasse ausserhalb des Jar Allgemeine Java-Themen 2
J Ist eine Instanz von einem bestimmten Object Typ? Allgemeine Java-Themen 6
B JavaFX fxml, die selbe Instanz der Klasse Allgemeine Java-Themen 4
E Auf Java-Objekt aus anderer Instanz zugreifen Allgemeine Java-Themen 26
DStrohma In abstrakter Klasse Konstruktor von Instanz implementieren Allgemeine Java-Themen 11
S OOP Objekte als Return-Werte: Einen Klon zurückgeben oder Instanz auf das Feld? Allgemeine Java-Themen 10
V Serialisierung von Instanz eigener Klasse Allgemeine Java-Themen 5
S Singleton Instanz löschen Allgemeine Java-Themen 5
Kr0e Reflection - Instanz einer Klasse erstellen, ohne Default-Constructor Allgemeine Java-Themen 15
sambalmueslie Benachrichtigung bei neuer Objekt-Instanz Allgemeine Java-Themen 5
L Object Instanz anhand eines Strings Allgemeine Java-Themen 10
M Object-Instanz in Date übersetzen Allgemeine Java-Themen 6
M Instanz "von außen" erstellen unterbinden Allgemeine Java-Themen 3
V Reflection - Field-Instanz und Annotations Allgemeine Java-Themen 6
S Instanz in einer Klasse erstellen, und dem Konstruktor die eigene Klasse mitgeben Allgemeine Java-Themen 4
J Instanz-Felder einer Klasse initialisieren Allgemeine Java-Themen 6
N Variablen eines Objektes (instanz) in einen Array lesen Allgemeine Java-Themen 7
M Instanz von Datenbankklasse Allgemeine Java-Themen 5
M Instanz erstellen Allgemeine Java-Themen 3
flashfactor Prüfen ob bereits eine Instanz gestartet ist Allgemeine Java-Themen 2
A Nur eine Instanz eines Programms ausführen Allgemeine Java-Themen 3
T Instanz einer Interface abgeleiteten Klasse erzeugen Allgemeine Java-Themen 3
I size einer instanz Allgemeine Java-Themen 9
minzel Instanz auslesen? Allgemeine Java-Themen 22
G überpüfen ob bereits instanz von java applikation läuft Allgemeine Java-Themen 4
B Instanz? Allgemeine Java-Themen 6
H Vererbung auch ohne erzeugung einer Instanz möglich? Allgemeine Java-Themen 3
B nur eine Instanz eines Programms laufen lassen Allgemeine Java-Themen 8
G Nur eine Instanz einer Applikation Allgemeine Java-Themen 4
G Instanz IDs Allgemeine Java-Themen 13
P Nur eine Instanz eines Programms zulassen, wie geht das? Allgemeine Java-Themen 15
J Instanz einer inneren Klasse Allgemeine Java-Themen 9
H Methode einer zur Laufzeit generierten Instanz aufrufen Allgemeine Java-Themen 2
C Best Practice Tiefe Kopie eines Arrays unbekannter Dimension und unbekannten Typs Allgemeine Java-Themen 4
C Methode für tiefe Kopie eines unbekannt (dimensionierten & typisierten) Feldes realisierbar? Allgemeine Java-Themen 7
reibi Kopie einer Liste Allgemeine Java-Themen 4
E tiefe Kopie nicht serialisierbarer Objekte Allgemeine Java-Themen 3
J Collections in Instanzattributen als Kopie übergeben Allgemeine Java-Themen 4
N for (String s : StringArray) : Kopie oder Verweis? Allgemeine Java-Themen 9
M "Kopie" von JLabels werden nicht gezeichnet Allgemeine Java-Themen 10
G Kopie eines FileReader Allgemeine Java-Themen 4
S Tiefe Kopie einer Baumstruktur als statische Methode Allgemeine Java-Themen 8
Z Echte Kopie eines Objektes erstellen Allgemeine Java-Themen 12

Ähnliche Java Themen

Neue Themen


Oben