Design Patterns und C# UML - Teil2 Claude Eisenmann 4. August 2005

UML - Teil2
Design Patterns und C#
Claude Eisenmann
4. August 2005
Inhaltsverzeichnis
• Rückblende
• Design Patterns
– Creational Patterns
– Structural Patterns
– Behavioural Patterns
– Architectural Patterns
• Umwandlung von UML nach C#
– Statische Struktur
– Beziehungen
– Interaktion
• Beispiel
Rückblende
Erinnerung
• Diagramme der UML 2
Erinnerung
Erinnerung
Erinnerung
Erinnerung
Design Patterns
Design Patterns – Einleitung
Definition
• Ein Design Pattern (oder Entwurfsmuster) beschreibt
eine in der Praxis erfolgreiche, generische Lösung für
ein mehr oder weniger häufig auftretendes,
wiederkehrendes Entwurfsproblem und stellt damit eine
wieder verwendbare Vorlage zur Problemlösung dar.
Design Patterns – Einleitung
Historie
• Der Architekt Christopher Alexander hatte in den 70er
Jahren eine Sammlung von Entwurfsmustern
zusammengestellt. In der Architektur hat sich diese Idee
jedoch bei weitem nicht so verbreitet wie später in der
Softwareentwicklung.
• Christopher Alexander sagte: „patterns are solutions to a
problem in a context“
• Christopher Alexander ist der Vater der Design Patterns
Design Patterns – Einleitung
Was sind Design Patterns?
•
•
•
•
Abstraktion und erneuter Einsatz von gutem OO-Design
Dokumentationsmittel
Erklären von Entwurfsentscheidungen
Benennen und Katalogisieren von häufig auftretenden
Entwurfsstrukturen
• Gemeinsames Vokabular und Kommunikationsmedium
(da man abstrakt über eine Softwarestruktur sprechen
kann)
• Unabhängig von der konkreten Programmiersprache
• Technik für Software-Architektur
Design Patterns – Einleitung
Was sie NICHT sind
• Ein Ziegelstein: ein Design Pattern ist von seinem
Nutzungskontext abhängig
• Eine Regel: ein Design Pattern passt sich nicht
mechanisch an
• Eine Methode: hilft nicht bei der Entscheidung, denn:
ein Design Pattern ist die Entscheidung
• Neu: bereits Lao-Tzu (-550 v.Chr.) arbeitete mit Patterns
Design Patterns – Einleitung
GoF
• GoF (kommt von Gang of Four) steht für Erich Gamma,
Richard Helm, Ralph Johnson und John Vlissides. Das
GoF-Buch ist ein Standardwerk im Bereich Software
Engineering über Entwurfsmuster.
Design Patterns –
Elements of Reusable Object-Oriented Software
von E. GAMMA, R. HELM, R. JOHNSON,J. VLISSIDES
ISBN 0201633612
Design Patterns – Einleitung
Dokumentation
• Die Beschreibung eines Entwurfsmusters durch die GoF
folgt diesem Schema:
Eigenschaft
Beschreibung
Name
Alle Patterns haben eindeutige Namen
Zweck
Zweck des Patterns
Synonyme
Andere bekannte Namen des Patterns
Problem
(Hinter-)Gründe für den Einsatz des Patterns
Lösung
Beschreibung der allgemeinen Struktur des
Musters
Design Patterns – Einleitung
Eigenschaft
Beteiligte Akteure
Beschreibung
Klassen, die an dem Muster beteiligt sind
Zusammenspiel
Zusammenspiel der beteiligten Klassen
Konsequenzen
Welche Vor- und Nachteile gibt es?
Implementierung
Praxisrelevante Tipps, Tricks und Techniken
sowie Warnung vor Fehlern, die leicht passieren
können
Beispielcode
Quellcodefragment, das den Einsatz des
Patterns zeigt
Praxiseinsatz
Wo wird das Muster bereits eingesetzt?
Querverweise
Wie spielt das Muster mit anderen Mustern
zusammen?
Design Patterns – Einleitung
• Beispiel:
Eigenschaft
Beschreibung
Name
Wartesaal
Zweck
Zweck des Patterns
Problem
Wir müssen warten
Lösung
Immer gemütlich und angenehm
Beteiligte Akteure
Stuhl, Tisch, Magazin, …
Zusammenspiel
Konsequenzen
Praxiseinsatz
Aktive oder passive Wartezeit?
Ablenkung?
Flughafen, Zahnarzt
Design Patterns – Einleitung
Klassifizierung
• Die GoF klassifiziert die Patterns (insgesamt 23) wie
folgt:
– Creational Patterns
Creational
• Abstract Factory, Builder, Prototyp, …
– Structural Patterns
Structural
• Adapter, Bridge, Composite, …
– Behavioral Patterns
• Chain of Response, Command, Iterator, … Behavioral
Design Patterns
Creational
Creational Patterns
Name
AbstractFactory
Builder
FactoryMethod
Prototyp
Singleton
Immer
relevant
Häufig
relevant
Selten
relevant
Design Patterns
Creational
Abstract Factory
• Die abstract factory findet Anwendung, wenn
– ein System unabhängig von der Art der Erzeugung
seiner Produkte arbeiten soll
– ein System mit einer oder mehrerer Produktfamilien
konfiguriert werden soll
– eine Gruppe von Produkten erzeugt und gemeinsam
genutzt werden soll
– in einer Klassenbibliothek die Schnittstellen von
Produkten ohne deren Implementierung bereitgestellt
werden sollen
Design Patterns – Abstract Factory
Creational
Design Patterns
Creational
Builder
• Entwickler verwenden den Builder, wenn
– zu einem komplexen Objekt unterschiedliche
Darstellungen existieren sollen
– die Konstruktion eines komplexen Objekts
unabhängig von der Erzeugung der Bestandteile
sein soll
Design Patterns – Builder
Creational
Design Patterns
Creational
FactoryMethod
• Die factory method findet Anwendung, wenn
– eine Klasse die von ihr zu erzeugenden Objekte nicht
erkennen kann
– die Unterklassen bestimmen, welche Objekte erzeugt
werden
Design Patterns – FactoryMethod
Creational
Design Patterns
Creational
Prototyp
• Ein Prototyp findet Anwendung, wenn
– die Erzeugung weiterer Instanzen einer Klasse teuer
ist und sich die Objekte ähneln
– die zu instanzierenden Klassen erst zur Laufzeit
bekannt sind
– eine Hierarchie von factories parallel zu einer
Hierarchie von Produkten vermieden werden soll
– die Objekte einer Klasse nur wenige
Zustandskombinationen einnehmen können
Design Patterns – Prototyp
Creational
Dieses Muster kommt hauptsächlich dann zum Einsatz,
wenn die Klassen der zu erzeugenden Objekte erst zur
Laufzeit spezifiziert werden, z.B. durch dynamisches
Laden.
Design Patterns
Creational
Singleton
• Das Einzelstück findet Verwendung, wenn
– nur ein Objekt zu einer Klasse existieren darf und ein
einfacher Zugriff auf dieses Objekt benötigt wird
– das einzige Objekt durch Unterklassenbildung
spezialisiert werden soll
• Anwendungsbeispiele sind:
– ein zentrales Protokoll-Objekt, das Ausgaben in eine
Datei schreibt
– Druckaufträge, die zu einem Drucker gesendet
werden, sollten nur in einen einzigen Puffer
geschrieben werden
Design Patterns
Structural
Structural Patterns
Name
Adapter
Bridge
Composite
Decorator
Facade
Flyweight
Proxy
Immer
relevant
Oft relevant
Selten
relevant
Design Patterns
Structural
Adapter
• Der Adapter findet Anwendung, wenn eine existierende
Klasse verwendet werden soll, deren Schnittstelle nicht
der benötigten Schnittstelle entspricht
• Im .NET Framework wird das Adapter Pattern in jeder
RCW (Runtime Callable Wrapper) verwendet
– System.String wird durch die RCW in BSTR (für
COM) umgewandelt
– HRESULT (wenn ein Fehler in der COM Bibliothek
aufgetreten ist) wird in System.Exception
umgewandelt
Design Patterns – Adapter
Structural
Design Patterns
Structural
Bridge
• Problem: normalerweise wird eine Implementierung durch
Vererbung der Abstraktion realisiert. Dieses kann jedoch
dazu führen, dass in der Vererbungshierarchie sowohl
Implementierungen als auch andere abstrakte Klassen zu
finden sind. Dieses macht die Vererbungshierarchie
unübersichtlich und schwer wartbar
Design Patterns – Bridge
Structural
• Lösung: werden die abstrakten Klassen und die
Implementierungen in zwei verschiedenen Hierarchien
verwaltet, gewinnt die Implementierung an
Übersichtlichkeit und zweitens wird die Anwendung
unabhängig von dieser
Design Patterns – Bridge
Structural
• Eine Brücke findet Anwendung, wenn
– Abstraktion und Implementierung erweiterbar sein
sollen
– eine dauerhafte Verbindung zwischen Abstraktion
und Implementierung verhindert werden soll
– Änderungen der Implementierung ohne
Auswirkungen für den Klienten sein sollen
– die Implementierung vor dem Klienten verborgen
bleiben soll
– die Implementierung von verschiedenen Klassen
gleichzeitig genutzt werden soll
Design Patterns – Bridge
Structural
Design Patterns
Structural
Composite
• Ein Kompositum findet Anwendung, wenn
– Implementierung von Teil-Ganzes-Hierarchien erfolgt
– Die Unterschiede zwischen einzelnen und
zusammengesetzten Objekten verborgen werden
sollen
Design Patterns - Composite
Structural
Design Patterns
Structural
Decorator
• Die Instanz eines Decorators wird vor die zu dekorierende Klasse
geschaltet
• Der Decorator hat die gleiche Schnittstelle wie die zu dekorierende
Klasse
• Aufrufe an den Decorator werden dann verändert oder unverändert
weitergeleitet (Delegation) oder sie werden komplett in Eigenregie
verarbeitet
• Der Decorator ist dabei "unsichtbar", da der Aufrufende gar nicht
mitbekommt, dass ein Decorator vorgeschaltet ist
Design Patterns – Decorator
Structural
Design Patterns
Structural
Facade
• Wenn ein Subsystem viele technisch orientierte Klassen
enthält, die selten von außen verwendet werden, hilft es,
eine Fassade zu verwenden
• Die Fassade ist eine Klasse mit ausgewählten
Methoden, die eine häufig benötigte Untermenge an
Funktionalität des Subsystems umfasst
• Sie vereinfacht den Umgang mit dem Subsystem
Design Patterns – Facade
Structural
Design Patterns – Facade
Structural
Facade
Adapter
Ja
Ja
Gibt es Vorgaben für eine Schnittstelle?
Nein
Ja
Muss Objekt polymorph verwendet werden
können?
Nein
Möglich
Ja
Nein
Gibt es bereits existierende Klassen?
Ist eine vereinfachte Schnittstelle notwendig?
Fazit: das Facade Pattern vereinfacht eine Schnittstelle, während ein
Adapter eine bereits bestehende Schnittstelle in eine gewünschte
konvertiert
Design Patterns
Structural
Flyweight
• Das Flyweight Pattern findet Anwendung, wenn
– es eine große Anzahl Objekte gibt, so dass alleine
schon die Anzahl zu Problemen führt
– ein Teil des Zustandes dieser Objekte kann in den
Kontext ausgelagert werden
– nach der Entfernung des Zustandes reduziert sich die
Anzahl verschiedener Objekte auf ein
überschaubares Maß
Design Patterns – Flyweight
Structural
Design Patterns
Structural
Proxy
• Ein Remote-Proxy ist ein lokaler Stellvertreter für ein
Objekt in einem anderen Adressraum. Er wird
beispielsweise in Netzwerkanwendungen verwendet
• Ein virtueller Proxy dient der Verzögerung teurer
Operationen auf den Zeitpunkt des tatsächlichen Bedarfs
• Ein Schutzproxy setzt Zugriffsrechte auf ein Objekt
durch
• Proxies kommen ebenfalls zum Einsatz, um beim
eigentlichen Zugriff auf das Objekt weitere Operationen
zu binden
Design Patterns – Proxy
Structural
Design Patterns
Behavioral
Behavioral Patterns
Name
Chain of responsibility
Command
Interpreter
Iterator
Mediator
Memento
Observer
State
Strategy
Template Method
Immer
relevant
Häufig
relevant
Selten
relevant
Design Patterns
Behavioral
Chain of Responsibility
• Vermeide die Kopplung des Auslösers einer Anfrage mit
seinem Empfänger, indem mehr als ein Objekt die
Möglichkeit erhält, die Aufgabe zu erledigen. Verkette
die empfangenden Objekte und leite die Anfrage an der
Kette entlang, bis ein Objekt sie erledigt
Design Patterns
Behavioral
Command
• Packt einen Befehl in ein Objekt. Dies ermöglicht es,
Klienten mit verschiedenen Anfragen zu parametrisieren,
Operationen in eine Schlange zu stellen, ein Logbuch zu
führen und Operationen rückgängig zu machen
Design Patterns
Behavioral
Interpreter
• Überführung einer Grammatik in Objekte zur
Konstruktion eines Interpreters. Dieser interpretiert den
Kontext.
Design Patterns
Behavioral
Iterator
• Ermöglicht den sequentiellen Zugriff auf die Elemente
eines zusammengesetzten Objekts, ohne seine
Repräsentation offen zu legen
Design Patterns – Iterator
Behavioral
• Mit dem .NET Framework wird regelmäßig dieses
Pattern in der Praxis benutzt:
int[ ] values = new int[ ] {1, 2, 3, 4, 5};
foreach(int i in values)
{
Console.Write(i.ToString() + " ");
}
=
int[] values = new int[] {1, 2, 3, 4, 5};
IEnumerator e = ((IEnumerable)values).GetEnumerator();
while(e.MoveNext())
{
Console.Write(e.Current.ToString() + " ");
}
Design Patterns
Behavioral
Mediator
• Definiert ein Objekt, welches das Zusammenspiel einer
Menge von Objekten in sich vereint. Vermittler
verhindern, dass Objekte direkt aufeinander Bezug
nehmen (lose Kopplung). Sie ermöglichen, das
Zusammenspiel der Objekte von ihnen unabhängig zu
variieren
Design Patterns
Behavioral
Memento
• Erfasst und stellt den internen Zustand eines Objektes
zur Verfügung, so dass das Objekt später in diesen
Zustand zurückversetzt werden kann
Design Patterns
Behavioral
Observer
• Definiert eine 1-zu-n-Abhängigkeit zwischen Objekten, so
daß die Änderung des Zustands eines Objekts dazu führt,
daß alle abhängigen Objekte benachrichtigt und
automatisch aktualisiert werden
Design Patterns – Observer
Behavioral
• Im .NET Framework
– Die Events sind die Subjects
– Die Delegates sind die Observers
public delegate void UpdateDelegate();
public class Subject
{
public Subject(){}
public UpdateDelegate UpdateEvent;
public void RaiseEvent1()
{
UpdateDelegate ev = UpdateEvent;
if (ev != null) ev();
}
public class Observer
{
public Observer(Subject theSubject)
{
theSubject.UpdateEvent += new
UpdateDelegate(Handle);
}
public void Handle()
{
Console.WriteLine("Observer - Update");
}
}
}
Design Patterns
Behavioral
State
• Ermöglicht es einem Objekt, sein Verhalten zu ändern,
wenn sein interner Zustand sich ändert. Es wird so
aussehen, als ob das Objekt seine Klasse gewechselt
hat
Design Patterns
Behavioral
Strategy
• Definiert eine Familie von Algorithmen, erfasst jeden
einzelnen und macht sie austauschbar. Das
Strategiemuster ermöglicht es, den Algorithmus
unabhängig von den ihn nutzenden Klienten zu variieren
• Im .NET Framework:
int[] aList = new int[] {5, 8, 47, 3, 789};
aList.Sort(aNewDefinedCompared);
Design Patterns – Strategy
Behavioral
Design Patterns
Behavioral
Template Method
• Definiert das Skelett eines Algorithmus in einer
Operation und delegiert einzelne Schritte an
Unterklassen. Die Verwendung einer Template Method
ermöglicht es Unterklassen, bestimmte Schritte eines
Algorithmus zu überschreiben, ohne seine Struktur zu
verändern
Design Patterns – Template Method
Behavioral
Design Patterns
Behavioral
Visitor
• Erfasst eine auf den Elementen einer Objektstruktur
auszuführende Operation als ein Objekt. Das
Besuchermuster ermöglicht es, eine neue Operation zu
definieren, ohne die Klassen der von ihr bearbeiteten
Elemente zu verändern
Design Patterns – Visitor
Behavioral
Design Patterns
Architectural
Architectural Patterns
Name
MVC
3-Tier
Immer
relevant
Häufig
relevant
Selten
relevant
Design Patterns
Architectural
MVC
• MVC(Model Viewer Controller) ist ein sehr bekanntes Pattern.
Dahinter verbirgt sich, daß allgemein beim Arbeiten mit Software
drei Blöcke definiert werden, die aus architektonischen Gründen
strikt voneinander getrennt werden sollten:
– Model: steht für das Datenmodell, also die Information und die
Struktur, die bearbeitet wird
– Viewer: hat nur die Aufgabe, den aktuellen Zustand des Models
darzustellen. Er trennt die Oberflächengestaltung von den Daten
– Controller: ist der Teil, der nach einer Benutzeraktion eine
Auswertung der Eingaben vornimmt und ggf. die Funktionalität
der Applikation aufruft, um das Model zu manipulieren (z.B.
neues Objekt anlegen, Daten ändern oder löschen etc.)
Design Patterns - MVC
Architectural
Design Patterns
Architectural
3-Tier
• Presentation Layer: accepting user input and generating
user output - the User Interface (UI)
• Business Layer: the processing of business rules and
task-specific behavior
• Data Access Layer: communicating with the physical
database using the APIs provided by that database
engine
Design Patterns – 3-Tier
Architectural
vonMicrosoft
Microsoft
von
Design Patterns
Methode
• Die guten Objekten finden: die Patterns schlagen
Abstraktionen vor, die nicht ins Auge fallen
– Composite
– Strategy
– State
höhereFlexibilität
Flexibilität und
und
höhere
erneuteEinsatzmöglichkeit
Einsatzmöglichkeit
erneute
Design Patterns – Methode
• Richtige Granularität auswählen: was soll gruppiert
und was getrennt werden?
– Facade
– Flyweigth
– Abstract Factory
– Builder
Design Patterns – Methode
• Die Schnittstelle spezifizieren: was gehört zum Objekt
und was nicht?
–
–
–
–
–
Memento: speichert die Zustände
Decorator: steigert die Schnittstelle
Proxy: delegierte Schnittstelle
Visitor: fasst die Schnittstellen zusammen
Facade: versteckt die komplexe Struktur eines
Objekts
Design Patterns
Zusammenfassung
• Vorteile
– Gemeinsames Vokabular
– Kapitalisieren von Erfahrung
– Höhere Abstraktionsebene für eine qualitätssichere
Software Architektur
– Reduziert die Komplexität
– Richtlinien/Lösungskatalog
Design Patterns – Zusammenfassung
• Nachteile
– Bemühen um Synthese beim: wieder Erkennen,
Abstrahieren, …
– Lehre, Erfahrung
– die Design Patterns lösen sich im Source Code auf
– Menge
• ein paar funktionieren ähnlich
• viel Verschiedene ein paar Design Patterns
basieren auch auf anderen
Design Patterns – Zusammenfassung
„Die Design Patterns sind wie Prosa:
Man verwendet sie, ohne dass es einem bewusst ist.
Aber wenn es einem dann bewusst wird,
denkt man intensiv darüber nach.“
Claude Eisenmann, August 2005
Umwandlung in C#
C#
Umwandlung in C# – Statische Struktur
Statische Struktur
• Das Klassendiagramm beschreibt die statische Struktur
der Objekte (Klassen) in einem System sowie ihre
Beziehungen untereinander.
• Die statische Struktur besteht aus:
– Klassen
– Schnittstellen
– Attributen
– Operationen
Umwandlung in C# – Statische Struktur
UML
Klasse
Abstrakte Klasse
C#
public class Catalog {
….
}
abstract public class Person {
….
}
Schnittstelle
interface IDeletable {
void Delete();
}
Package
namespace Library {
…
}
Umwandlung in C# – Statische Struktur
UML
Attribute
Operationen
C#
public class Person {
protected string mName;
private string mFirstName;
public int BirthDate;
private static mMajorityAge =18;
}
public class Person {
public abstract int Calculate();
public static void SetMajAge(int
theAge) {
…
}
public int Age
{
get { return … }
}
Umwandlung in C#
Beziehungen
• Die Klasse wird als Rechteck dargestellt. Die Klassen
werden durch Linien miteinander verbunden. Diese
Linien stellen verschiedene Beziehungstypen dar:
– Vererbung: stellt eine Verallgemeinerung von
Eigenschaften dar: Spezialisierung, Generalisierung
– Abhängigkeit: Beziehung zwischen zwei
Modellelementen, die zeigt, dass eine Änderung in
dem einen (unabhängigen) Element eine Änderung in
dem anderen (abhängigen) Element notwendig macht
Umwandlung in C# – Beziehungen
– Assoziation: allgemeine Beziehung zwischen zwei
Klassen, keine weiteren Aussagen über konkrete
Realisierung
– Aggregation: „Ist-Teil-von-Beziehung„, kann noch um
Multiplizitäten erweitert werden
– Komposition: stärkere Form der Aggregation,
realisiert physikalisches Enthaltensein
– Assoziationsklasse: ein Modellelement, das sowohl
über die Eigenschaften einer Klasse als auch über die
einer Assoziation verfügt
Umwandlung in C# – Beziehungen
UML
C#
public class Person {
…
}
Vererbung
Abhängigkeit
public class Customer : Person {
Guid mId;
....
}
class Customer {
...
public void Print() {
Printer aPrinter =
PrinterFactory.getInstance();
aPrinter.Print(this.Name);
...
}
}
Umwandlung in C# – Beziehungen
UML
C#
public class A1 {
private B1 mB1;
}
public class A2 {
private B2[ ] mB2;
}
Assoziation
public class A3 {
private ArrayList B3;
}
public class A4 {
private HashTable B4;
}
Umwandlung in C# – Beziehungen
UML
Rolle
Rolle
Assoziation
C#
public class Man {
private Womam mWife;
}
private class Woman {
private Man mHusband;
}
public class Person {
private Person mChef;
}
Umwandlung in C# – Beziehungen
UML
Agregation
Komposition
C#
Genau das gleiche wie für die
Assoziation
public class Book {
private string mTitle;
private class Page {
….
}
}
Umwandlung in C# – Beziehungen
UML
C#
public class Job
{
private string mTitle;
private float mSalary;
Assoziationsklasse
private Company mEmployer;
private Person mEmploye;
}
Umwandlung in C#
Interaktion
UML
C#
public class Object1 {
int aInt = mObject2.DoSomething1();
mObject2.DoSomething2(987);
…
}
public class Object2 {
public int DoSomething1() {
…
}
public void DoSomething2(int theParam) {
…
}
}
Umwandlung in C# – Statische Struktur
Beispiel
Beispiel
Beispiel
Beispiel – Strategy
• Die Daten werden durch die FolderStrategy oder
FileTypeStrategy gesammelt
Beispiel – Observer
• Beziehung zwischen den Subject (ExplorationStrategy)
und den Observer (ExplorationObserver)
• Wenn die „Exploration“ fertig ist, wird die Anzeige
aktualisiert
Beispiel – Adapter
• ListView muss sich nach der Suche aktualisieren
• Die ListViewAdapter Klasse leitet von der .NET ListView
ab und hat die Signatur der ExplorationObserver Klasse
Beispiel – Template Method
• Die Template Method ist eine Methode, die abstrakte
Methoden aufruft
• Die abgeleiteten Klassen überschreiben die abstrakten
Methoden
Beispiel – Singleton
• SystemIcons ist ein Puffer aller System Icons
• IconReader liest die Icons vom System, ohne sie zu
lagern
Beispiel – Wrapper
• Die Methoden, die Icons lesen, sind in APIs
implementiert
• Der IconReader versteckt die komplexen Aufrufe der
APIs Methoden
Bücher
Professional UML with Visual Studio .NET
von Tony Loton, Kevin McNeish, Andrew Filev
ISBN 1861007957
Design Patterns Explained: A New Perspective on
Object-Oriented Design
von Alan Shalloway, James Trott
ISBN 0201715945
UML Distilled 3/e
Von Martin Fowler
ISBN 0321193687
Webseiten
•
http://de.wikipedia.org/wiki/Design_Pattern
Wikipedia : Entwurfmuster
•
http://www.jeckle.de/uml-glasklar/
Die Internetseiten von dem UML 2 Glasklar Buch
•
http://ebus.informatik.uni-leipzig.de/www/media/lehre/seminarpioniere04/poetzsch-ausarbeitung-gamma.pdf
Entwurfmuster: Ausarbeitung von Thomas Pötsch
Kontakt
Claude Eisenmann
Technischer Architekt
E-Mail: [email protected]
Frage – Antwort