Adaptor, Abstract Factory

Status
Nicht offen für weitere Antworten.

pat270881

Bekanntes Mitglied
Hi,

kann mir jemand bitte versuchen, diese beiden Patterns zu erklären und vielleicht ein real-world Beispiel dazu zu geben, wo diese Patterns angewendet werden? - Ich habe schon auf verschiedensten Seiten mir die Klassendiagramme dazu zu Gemüte geführt, aber mir ist das einfach nicht ganz klar...:(

1) Adapter:
Ich habe eine abstrakte Klasse oder ein Interface namens A, das bestimmte Methoden anbietet. Dieses Interface oder abstrakte Klasse kann von verschiedenen konkreten Klassen implementiert werden – das heißt die Methoden vom Interface oder abstrakten Klassen werden in der konkreten Klasse implementiert. Jetzt habe ich eine andere konkrete Klasse C von der ich die Funktionalität verwenden möchte, jedoch implementiert diese konkrete Klasse C das Interface od. abstrakte Klasse A nicht. Daher definiere ich eine konkrete Klasse B, die das Interface oder die abstrakte Klasse A implementiert. In dieser Klasse B wird ein Objekt der Klasse C erzeugt. Und dann wird in der entsprechenden Methode von der konkreten Klasse B mit dem Objekt der Klasse C die korrespondierende Methode der Klasse C aufgerufen.
=>Das heißt in meiner Main-Klasse definiere ich noch immer Objekte von dem Interface A das dann ein Objekt von der konkreten Klasse B erzeugt in der dann irgendwann mal Methoden der adaptierten Klasse C aufgerufen wird.
Die Frage ist nun, wenn ich das richtig interpretiert habe, dass ich immer Objekte vom Interface A erzeuge und nicht einfach die Methoden der Klasse C aufrufe?


lg
patrick
 

SnooP

Top Contributor
Ja... ein Adapter ist wie der Name schon sagt etwas mit dem man etwas was nicht zusammenpasst - passend macht ;)

Bei Klassen definieren Interfaces also Schnittstellen die Zugangsmöglichkeiten für Features bzw. konkreter Methoden. Ein häufiges Problem ist, dass man auf ein Framework zugreifen muss, dass ein komplett anderes Interface anbietet - sprich völlig inkompatibel ist, zu dem, was man sonst so geschrieben hat.. (bildlich der Versuch mit einem amerikanischen Netzstecker an eine europäische Steckdose zu kommen). Jetzt hat man die Möglichkeit einen Adapter zu schreiben, der dazwischengeschaltet wird - die Objekte des ursprünglichen Programmcodes interagieren dann nicht direkt mit dem Framework, sondern immer über den Adapter.. anstatt jetzt also den bisherigen Code umständlich anzupassen, dass er "auch" mit dem Framework arbeiten kann und andersrum, geht alles über den Adapter...

Vor allem wichtig und sinnig einsetzbar ist ein Adapter dann, wenn das Interface einer bisherigen Klasse (A) bereits in vielen konkreten Unterklassen genutzt und konkretisiert wird - bietet das zugekommene Framework eine Funktionalität, die sich inhaltlich innerhalb der bisherigen Anwendung einsetzen lässt, dann kann eine Unterklasse der bisherigen Klasse (A) als Adapter generiert werden, die eine Referenz auf das Framework-Objekt erhält. Die Methoden der Schnittstelle greifen dann in dieser Klasse auf die konkreten Methoden des referenzierten Objekts zu (die natürlich alle ganz anders heißen, sonst könnte man die Klasse ja direkt einbauen...).

Das zu 1)... ich glaub die Abstract-Factory war auch nen Thema? ;) ... die GoF hat hier das Beispiel mit den verschiedenen Widgets gegeben - also verschiedene Darstellungsformen inhaltlich selbiger Fensterdekorationen (Knöppe, Fensterrahmen,...). Konkrete Unterklassen einer AbstractFactory realisieren jeweils konkrete Objekte ihrer zugehörigen Widgets... das Produkt hat dabei auch wieder ein übergeordnetes Interface - d.h. sie ähneln sich in elementaren Teilen... Knöppe z.B. kann man immer mit der Maus anclicken etc... - aber sie besitzen unterschiedliche Ausprägungen.
Allein durch den Wechsel der konkreten Factory-Klasse kann jetzt das Widget ausgewechselt werden - was natürlich ne enorme Flexibilität bedeutet... - wichtig ist hier das Konzept der abstrakten Oberklassen bei Produkt und Factory, nur dann kann man später in der Anwendung flexibel von einer Produktart zur anderen wechseln (im Beispiel sinds die versch. Widgets).

Ich hoffe es wurde etwas heller - ansonsten - frag nach ;)
 

pat270881

Bekanntes Mitglied
Hi,

ookay, jetzt ist mir der Adapter schon sehr viel klarer. Leider bin ich jetzt grad beim Abstract Factory und wenn ich mir auf der http://www.dofactory.com/Patterns/PatternAbstract.aspx Seite zB. das UML-Diagramm und den Beispielcode und die Erklärung ansehe, dann stehe ich leider an... :cry: Wie funktioniert dieser Pattern und für was ist dieses komplizierte Gerüst gut? - Hast du vielleicht noch einmal so eine gute Erkärung auf Lager..? :?

lg
patrick

PS: Was mir grundsätzlich da immer Unklar ist, warum zB. wie bei dem Beispielcode auf der von mir angegebenen Url immer ein Objekt vom abstrakten Typ definiert wird aber in dem Objekt dann ein Objekt von der abgeleiteten Klasse erzeugt wird..?? zB. AbstractFactory factory1 = new ConcreteFactory1();
 

SnooP

Top Contributor
Nunja - du solltest dir im Allgemeinen mal klar machen, was man mit Schnittstellen und Abstrakten Klassen überhaupt so anstellen kann - warum sowas sinnvoll ist.

Bei Abstract-Factories wie beim UML-Diagramm siehst du auf der einen Seite Produkte (A und B) sowie Factory-Klassen für die Produkte A und B. Der Umweg über die abstrakten Klassen wird deswegen gemacht, damit man verschiedene Ausprägungen unter ein und demselben Typ speichern kann... das ganze wird dadurch komplett austauschbar und sehr viel flexibler. Der Client greift dabei grundsätzlich nur auf die abstrakten Klassen zu, bzw. referenziert auf die abstrakten Klassen. Das kann er, da die Methoden ja durch die abstrakten Klassen vorgegeben und in den konkreten Realisierungen - also den Unterklassen überschrieben werden. Diese konkreten Factories können durch die überschriebenen Methoden die konkreten Produkte erzeugen - die so erzeugten Objekte werden vom Client aber immer noch lediglich über deren abstrakte Oberklasse referenziert. Der Vorteil - man kann zur Laufzeit sehr einfach die Produkte austauschen, lediglich die entsprechenden Factory-Methoden müssen aufgerufen und die Objekte entsprechend zugewiesen werden.
Mit Hilfe der schönen Polymorphie ist es dann völlig abhängig davon, wie die Methoden in den konkreten Objekte jeweils überschrieben wurden... das Beispiel mit den netten Tieren unter der URL ist schon ganz sinnig...
Ich hatte ja das mit den Widgets gegeben... schau dir mal bei Gelegenheit "Entwurfsmuster" (Design Patterns) von Erich Gamma et al. an - dort ist das eigentlich ganz prima beschrieben... es dauert zwar meistens immer bis mans wirklich 100% verstanden hat... aber es lohnt sich ;)

Wenn du's noch nich verstanden hast - probiers einfach mal aus... wirst sehen, dass das ganze designtechnisch wirklich ne hübsche Sache ist...
 

pat270881

Bekanntes Mitglied
Danke wieder für diese ausführliche Antwort. Ich würde mir das Buch gerne ansehen, leider ist das gerade nicht verfügbar und kaufen möchte ich es nicht unbedingt.. - 50 euro.

Ich schreib den code von der site mal in java in eclipse und schau ob mir das aufschluss gibt. :-/

lg
 

mic_checker

Top Contributor
Ich kann "Head First Design Patterns" nur empfehlen - teils etwas unkonventionell, aber vielleicht gerade deswegen so gut.
 

pat270881

Bekanntes Mitglied
Hi,

So ich versuch das ganze jetzt nochmal anhand des Tierbeispiels mit eigenen Worten zu rekapitulieren:

Ich habe meine AbstractFactory (ContinentFactory) Klasse von denen zwei konkrete Klassen abgeleitet werden AmericaFactory und AfricaFactory, die beide die Methoden der AbstractFactory Klasse implementieren und in den Methoden Objekte der konkreten Klassen der Produkte (Wolf, Löwe, Bison, Gnu) erzeugt werden.

Das heißt es wird zuerst mal ein AfricaFactory Objekt erzeugt aber mit dem generalisierten Typ ContinentFactory. Danach wird ein AnimalWorld Objekt erzeugt - in dem Konstruktor wird jeweils von der Klasse AfricaFactory einmal die Methode CreateFleischfresser und einmal die Methode CreatePflanzenfresser aufgerufen - was konkrete Tierobjekte erzeugt und in den generalisierten Typen Pflanzenfresser und Fleischfresser gespeichert werden. Die Methode (runFoodChain) von AnimalWorld wird aufgerufen und je nachdem welches konkrete Tierobjekt in dem Fleischfresser Objekt gespeichert ist, wird die Eat-Methode dieser konkreten Tier-Klasse aufgerufen.

Soweit so gut.

Das heißt, man kann einfach neue FactoryKlassen hinzufügen zb. EuropeFactory, die nur die zwei entsprechenden Klassen der AbstractFactory Klasse implementieren muss ohne sonst was zu ändern. - Man muss nur im MainApp ein neues Statement ContinentFactory europe = new EuropeFactory(); hinzufügen. Wenn man dann den AnimalWorld Konstruktor aufruft erwartet der sowieso ein Objekt der abstrakten Klasse und ruft dann die konkreten Methoden der EuropeFactory Klasse auf. Weiters kann man viele konkrete Tierklassen bauen und muss nichts verändern sondern nur in der AmericaFactory Klasse oder AfricaFactory Klasse ein neues Objekt von der jeweiligen neuen Klasse die dazu kommt erzeugen. Das heißt man kann in den CreatePflanzenfresser und CreateFleischfresser beliebig neue Objekte hinzufügen solang diese die abstrakten Klassen Fleischfresser und Pflanzenfresser implementieren.

Das heißt weiter, dass man bei diesem Pattern eine Collection von Objekten - konkreten Klassen hat, die eine abstrakte Klasse implementieren und beim Client es völlig egal ist welche Objekte das sind, da er diese sowieso sozusagen castet auf den abstrakten Typ. (also können hier beliege Objekte verwendet werden. Er verwendet auch nur die abstrakten Methoden der abstrakten Methode, wobei hier dann je nachdem welches konkrete Objekt sich hinter dem abstrakten Objekt verbirgt die entsprechende Methode aufgerufen wird.
Innerhalb der konkreten Klassen können dann konkrete Objekte erzeugt, die widerum eine abstrakte Klasse implementieren, denn im Client wird wieder nur auf den abstrakten Typ "gecastet". Das heißt es können die verschiedensten Tiere hinzugefügt werden, die die abstrakte Klasse Pflanzenfresser oder Fleischfresser implementiert und dann in der konkreten FactoryKlasse erzeugt werden.

Also würde ich sagen, die Vorteile bei diesem Pattern sind, dass immer abstrakte Klassen zwischen dem Client und den konkreten Klassen dazwischengeschalten sind und somit können beliebig diese konkreten Klassen ersetzt oder neue hinzugefügt werden. Sei es jetzt bei den konkreten Factoryklassen oder bei den konkreten Produktklassen.

Habe ich das jetzt komplett richtig verstanden...?:-/

Könnt' ihr mir vielleicht jetzt noch konkrete Anwendungsgebiete von diesem Pattern sagen bzw. was jetzt die konkreten Vor- und Nachteile bezogen auf die Wiederverwendung sind? - Ich habe das ja ein bißchen schwammig formuliert... :?:

lg
patrick

PS: Ich habe die Klassennamen des Beispiels von der Seite die ich im ersten Posting angegeben habe ins Deutsche übersetzt ;)
 

SnooP

Top Contributor
Ja - du hast das denke ich komplett richtig verstanden ;) - damit sollten die Vorteile doch auch klar sein - du hast sie zumindest schon versucht zu erklären.
Man kann grundsätzlich neue Produkttypen hinzufügen und auch weitere konkrete Produkte - alles steuerbar über zentrale Factory-Klassen... durch die übergeordnete Schnittstelle kann man immer auf diesen Typ kasten - die konkreten Objekte realisieren nur andersartige Ausprägungen ihres Obertyps - erfüllen also die vorgegebene Schnittstelle - sind aber intern jeweils anders implementiert und unterscheiden sich so... ergo: überall ist alles ganz prima austauschbar und flexibel ;)

Anwendungsbeispiel war das von mir zitierte Widget-Dingen ;) - also versch. Fensterdekorationsarten (Button Typ A, Typ B etc...).
 

pat270881

Bekanntes Mitglied
Supi, DANKE, dann sollte der ja ungefähr jetzt klar sein. :wink:

Bezüglich des Facade Patterns - wenn ich mir wieder das Beispiel auf der page ansehe. Dann ist dort ja der Facade die Mortgage Klasse. Die Mortgage Klasse erzeugt dann einfach Objekte von den Subsystem-Klassen Loan, Bank und Credit und ruft deren Methoden auf. Das ist eigentlich alles, wenn ich das richtig verstanden habe.

Was ist jetzt der Sinn dieses Patterns bzw. Vorteil widerum aus Wiederverwendungssicht?

mfg
patrick
 

SnooP

Top Contributor
Nunja - ne Fassade hat nicht direkt die Aufgabe des Erzeugens von Objekten des Subsystems, sondern vielmehr die zentrale Ansteuerung von Funktionen des Subsystems.

Das hat bei sehr komplexen Systemen mit unheimlich vielen Klassen den Vorteil, dass man bei der Programmierung eines Clients lediglich auf Methoden der Fassade zugreifen muss und nicht 1000 Klassen anschauen muss, um zu gucken, welches Objekt jetzt für was zuständig ist...
Nen Beispiel hier ist wieder nen relativ umfangreiches Framework mit diverser Funktionalität die unheimlich verteilt ist intern... die Fassade des Frameworks bietet einen einheitlichen Zugriff über einen zentralen Wartepunkt ;) wenn man so will..
Insbesondere dann sinnvoll, wenn von vornherein klar ist, dass für das Erfüllen einer ganz bestimmten Aufgabe eine feste Reihenfolge von Objekten mit entsprechenden Methodenaufrufen gebraucht werden - diese zentralen Aufgaben werden dann in Methoden der Fassade gespeichert...

Prinzipiell ein recht einfaches Pattern...

Wenn du übrigens noch mehr über Patterns erfahren möchtest, solltest du evtl. das in mehreren Threads kapseln ;) - und ob ich bei den kommenden dann auch noch Ahnung habe, kann ich dir auch nicht versprechen ;)...

Manchmal ists sinnvoll sich einfach doch nen bissel länger damit zu beschäftigen - insb. das von mir zitierte Buch sei dir nahegelegt - gibt es eigentlich auch in jeder Unibibliothek mehrfach...
 

Bleiglanz

Gesperrter Benutzer
Ein Standardbeispiel aus der Java API, ist eigentlich nicht schwer zu verstehen:

die AbstractFactory:

java.lang.Iterable<T>

das AbstractProduct

java.util.Iterator<T>

die ConcreteFactories:

fast alle Collection-Typen in java.util

die Products:

kennt man nicht so genau, das sind innere Klassen und ListIteratoren usw.
 

pat270881

Bekanntes Mitglied
Hallo,

so dann bin ich jetzt beim State. :? Ich habe mir wieder das Beispiel auf der einen Seite dazu angesehen mit den Kontoeinzahlungen und Auszahlungen bzw. auch ins Java übersetzt und in eclipse laufen lassen.

Meiner Meinung nach beruhen viele Design Patterns auf dem selben Prinzip. Es werden immer generalisierte Objekte definiert in denen sich dann Objekte von konkreten Klassen befinden. Somit kann ich dann immer eine Unterklassen hinzufügen und es ändert sich nur das new SilverState zb. wenn ich diese Klasse austausche. Wie in diesem Beispiel State state = new SilverState(0.0, this);

In dem Pattern gehts darum, dass ich in meiner Kontextklasse (Account) nur (in diesem Beispiel nur eines) ein Objekt von der Oberklasse State definiere, aber in diesem Objekt ein Objekt einer konkreten Unterklasse - SilverState erzeuge. Dadurch wird das Konto mit Anfangswerten initialisiert. Die Klasse State definiert auch die abstrakten Methoden für das abheben, einzahlen, etc. Das heißt, wenn man jetzt zB. was vom Konto behebt wird in der Methode Deposit mit dem generalisierten state-Objekt die Deposit Methode aufgerufen und jenachdem welches Objekt sich gerade in dem state-Objekt befindet (SilverState, RedState, GoldState) wird die entsprechende Methode dazu aufgerufen. Dann wird der neue Kontostand im StateChangeCheck berechnet, falls sich das Konto jetzt zB. im negativen Bereich befindet, wird ein neues Objekt der konkreten Unterklasse RedState erzeugt und das generalisierte State Objekt state erzählt eine Referenz auf dieses Objekt und somit wird bei einer neuerlichen Kontobewegung die Methoden der RedState Klasse verwendet.

Vorteile aus Sicht der Wiederverwendung wäre für mich hier: Man kann beliebige Klassen von Zuständen hinzufügen - solange sie die Methoden der generalisierten State Klasse implementieren können sie von der Context Klasse in Anspruch genommen werden ohne das sonst was am Code geändert werden muss. Klassen können auch beliebig ausgetauscht werden, jedoch muss ich das bei der Objekt-erzeugung in den anderen Klassen beachten, falls sich die Klassennamen ändern. (Also wenn ich zB. jetzt SilverState Klasse gegen GreenState Klasse austausche, dann muss ich auch die Objekterzeugungen zB. in der RedState Klasse, wo ja ein SilverState Objekt erzeugt wird entsprechend in GreenState umbenennen.

Was sagst du bzw. ihr dazu? - Habe ich das alles richtig verstanden, gibts sonst noch konkrete Vorteile, die dieses Pattern aufweise oder irgendwelche Hintergründe die ich noch nicht angesprochen habe? :bahnhof: Bzw. konkrete real-world Anwendungen?

lg
patrick
 

SnooP

Top Contributor
Nunja.. die Wiederverwendung beim State-Pattern ist jetzt nicht soo das Thema meiner Meinung nach... - Wiederverwendung ergibt sich durch OOP natürlich per Definition ;) - dadurch, dass in Design-Patterns wie du schon gesagt hast, immer auf übergeordnete Schnittstellen geachtet wird, kann das meiste beliebig erweitert werden...

Beim State-Pattern gehts um eine Umsetzung von Zustandsbasiertem Verhalten... insb. wenn man sog. Statecharts (Zustandsdiagramme) kennt, wäre das State-Pattern ein Ansatz (wenn auch ein sehr kostspieliger) Zustände und Zustandsübergänge in einer Programmiersprache umzusetzen... und zwar auch so, dass diese automatisch per Codegenerierung erfolgen könnte...

Aber zur Wiederverwendung - natürlich können jetzt beliebige Zustände noch hinzugefügt werden... ist also ganz prima erweiterbar...

(ich hatte übrigens gehofft, dass du deine Antwort doch in einen neuen Thread packst, damit auch andere hier nochmal reingucken können... so hat das Thema das gerade diskutiert wird nix mehr mit dem Topic-Titel zu tun!)
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
Say abstract class und Objekt erzeugen - Dringend Hilfe Java Basics - Anfänger-Themen 10
S Wann Methode abstract? Java Basics - Anfänger-Themen 10
O Verständniss Problem bei abstract class Java Basics - Anfänger-Themen 7
H abstract und interface Java Basics - Anfänger-Themen 4
H abstract - Wozu? Java Basics - Anfänger-Themen 6
B Interface vs Abstract Java Basics - Anfänger-Themen 2
B Objekte zählen/ Vererbung/ Kopplung/ Interface/ Abstract Class Java Basics - Anfänger-Themen 5
W Vererbung, abstract und Konstruktoren Java Basics - Anfänger-Themen 30
J OOP Wie sollte ich das organisieren (Abstract? Interface?) Java Basics - Anfänger-Themen 33
Azazel Ist die abstract class das selbe wie ein interface ? Java Basics - Anfänger-Themen 33
S Compiler-Fehler not abstract and does not override Java Basics - Anfänger-Themen 9
M abstract method does not override or implement.... Java Basics - Anfänger-Themen 7
B Fehler : class is abstract and does not overwrite Java Basics - Anfänger-Themen 2
B klasse abstract Java Basics - Anfänger-Themen 9
R Wofür abstract? Java Basics - Anfänger-Themen 29
E Klasse abstract machen Java Basics - Anfänger-Themen 3
G Schlüsselworte Bedeutung von abstract Java Basics - Anfänger-Themen 2
C Liste mit Attribut Abstract vererben Java Basics - Anfänger-Themen 11
Y Theorie: Abstract Method Java Basics - Anfänger-Themen 6
P Problem mit Eclipse "must be declared as abstract" Java Basics - Anfänger-Themen 3
O Abstract Method & Generics Java Basics - Anfänger-Themen 10
B abstract static Java Basics - Anfänger-Themen 16
T abstract class Java Basics - Anfänger-Themen 8
K abstract Java Basics - Anfänger-Themen 8
W abstract static Java Basics - Anfänger-Themen 3
F does not overwride abstract method Java Basics - Anfänger-Themen 2
G Verständnisfrage zum Interface und Abstract Java Basics - Anfänger-Themen 3
A in abstract Klasse private Variablen Java Basics - Anfänger-Themen 3
J abstract & Polymorphismus Java Basics - Anfänger-Themen 11
K Problem mit Abstract Table Model Java Basics - Anfänger-Themen 5
D Fehlermeldung "Time is not abstract" Java Basics - Anfänger-Themen 6
T Problem mit Abstract Windowing Toolkit(simples Problem) Java Basics - Anfänger-Themen 8
K <class> is not abstract and does not override abstract Java Basics - Anfänger-Themen 5
S Brauche Hilfe bei "abstract" Java Basics - Anfänger-Themen 12
G fenster abstract Java Basics - Anfänger-Themen 18
R abstract class <-> instance Java Basics - Anfänger-Themen 6
G Abstract Class - Abstract Method Java Basics - Anfänger-Themen 4
I Java Generics factory method Java Basics - Anfänger-Themen 2
Z Factory-Entwurfsmuster Java Basics - Anfänger-Themen 1
I Desing Patterns / Factory Java Basics - Anfänger-Themen 4
U UML Factory Method Java Basics - Anfänger-Themen 4
U Factory in anderer Klasse Java Basics - Anfänger-Themen 2
T Klassen Factory und Dynamsiche KlassenNamen Java Basics - Anfänger-Themen 6
nrg Wohin mit Factory Methoden? Java Basics - Anfänger-Themen 3
S OOP Factory Pattern Java Basics - Anfänger-Themen 2
D Factory Java Basics - Anfänger-Themen 7
S OOP Warum gleiche Instanz der Klasse? (Factory-Muster) Java Basics - Anfänger-Themen 13
A Factory Pattern Java Basics - Anfänger-Themen 2
M Factory mit String / Frage zu Generics Java Basics - Anfänger-Themen 2
M Factory Pattern Ansatz falsch? Java Basics - Anfänger-Themen 6
S Objektrückgabe durch Factory-Methode in abstrakten Klassen Java Basics - Anfänger-Themen 4

Ähnliche Java Themen

Neue Themen


Oben