Dirk Richter
Software-Entwicklung und Architektur
Hintergrundwissen zu Abstract Factory und Factory Method
Inhaltsverzeichnis
Hintergrund
Design Patterns sind bewährte Lösungen für wiederkehrende Probleme in der Softwareentwicklung. Zwei häufig genutzte Erzeugungsmuster sind Factory Method und Abstract Factory. Sie helfen, die Erzeugung von Objekten zu kapseln und flexibel zu gestalten.
Factory Method Pattern
Die Factory Method ist ein Entwurfsmuster, bei dem die Instanziierung eines Objekts einer Methode überlassen wird, die von Unterklassen überschrieben werden kann. Dadurch kann die Basisklasse die genaue Klasse des zu erzeugenden Objekts zur Laufzeit bestimmen.
Merkmale
- Eine einzelne Methode zur Objekterzeugung (
Factory Method
). - Die Basisklasse definiert die Methode abstrakt oder virtuell.
- Unterklassen bestimmen, welches konkrete Produkt erzeugt wird.
Beispiel in C#
1// Produkt
2public interface IButton
3{
4 void Render();
5}
6
7// Konkrete Produkte
8public class WindowsButton : IButton
9{
10 public void Render() => Console.WriteLine("Rendering Windows Button");
11}
12public class LinuxButton : IButton
13{
14 public void Render() => Console.WriteLine("Rendering Linux Button");
15}
16
17// Erzeuger
18public abstract class Dialog
19{
20 public abstract IButton CreateButton(); // Factory Method
21
22 public void RenderDialog()
23 {
24 var button = CreateButton();
25 button.Render();
26 }
27}
28
29// Konkrete Erzeuger
30public class WindowsDialog : Dialog
31{
32 public override IButton CreateButton() => new WindowsButton();
33}
34public class LinuxDialog : Dialog
35{
36 public override IButton CreateButton() => new LinuxButton();
37}
Wichtig:
Die Factory Method ist hier die Methode CreateButton()
. Die Methode RenderDialog()
verwendet die Factory Method, ist aber selbst keine Factory Method.
Abstract Factory Pattern
Das Abstract Factory Pattern bietet eine Schnittstelle zum Erzeugen von Familien zusammengehöriger Objekte, ohne deren konkrete Klassen zu kennen. Es ermöglicht die Erstellung von mehreren Produkttypen (z. B. Button, Checkbox), die zusammen verwendet werden sollen.
Merkmale
- Eine Factory-Klasse (oder Interface) mit mehreren Factory Methods.
- Jede Factory erzeugt eine vollständige Produktfamilie.
- Der Nutzer arbeitet nur mit der Factory, nicht mit den konkreten Produktklassen.
Beispiel in C#
1// Produktfamilie: Button & Checkbox
2public interface IButton
3{
4 void Render();
5}
6public interface ICheckbox
7{
8 void Check();
9}
10
11// Konkrete Produkte Windows
12public class WindowsButton : IButton
13{
14 public void Render() => Console.WriteLine("Rendering Windows Button");
15}
16public class WindowsCheckbox : ICheckbox
17{
18 public void Check() => Console.WriteLine("Checking Windows Checkbox");
19}
20
21// Konkrete Produkte Linux
22public class LinuxButton : IButton
23{
24 public void Render() => Console.WriteLine("Rendering Linux Button");
25}
26public class LinuxCheckbox : ICheckbox
27{
28 public void Check() => Console.WriteLine("Checking Linux Checkbox");
29}
30
31// Abstract Factory
32public interface IGUIFactory
33{
34 IButton CreateButton();
35 ICheckbox CreateCheckbox();
36}
37
38// Konkrete Factories
39public class WindowsFactory : IGUIFactory
40{
41 public IButton CreateButton() => new WindowsButton();
42 public ICheckbox CreateCheckbox() => new WindowsCheckbox();
43}
44public class LinuxFactory : IGUIFactory
45{
46 public IButton CreateButton() => new LinuxButton();
47 public ICheckbox CreateCheckbox() => new LinuxCheckbox();
48}
Wichtig:
Die Objekterzeugung erfolgt hier über Factory-Objekte. Der Anwender kennt nur die Factory und deren Interface, nicht die konkreten Produktklassen.
Statische Factory-Methoden bei Domain-Objekten
In C# werden bei Domain-Objekten oft statische Factory-Methoden verwendet, um die Erzeugung zu kapseln und Validierung zu ermöglichen.
Beispiel
1public class EmailAddress
2{
3 public string Value { get; }
4
5 private EmailAddress(string value)
6 {
7 Value = value;
8 }
9
10 public static EmailAddress Create(string address)
11 {
12 if (IsValid(address))
13 return new EmailAddress(address);
14 throw new ArgumentException("Invalid email address");
15 }
16
17 private static bool IsValid(string address)
18 {
19 return address.Contains("@");
20 }
21}
Vergleich: Factory Method vs. Abstract Factory
Pattern | Zweck | Struktur | Beispiel |
---|---|---|---|
Factory Method | Einzelnes Produkt erzeugen | Einzelne Methode | CreateButton() |
Abstract Factory | Familie von zusammengehörigen Produkten | Interface/Klasse mit mehreren Methoden | CreateButton(), CreateCheckbox() |
- Factory Method: Die Factory Methode ist Bestandteil jeder Klasse, die ein Produkt erzeugen möchte und wird typischerweise von Unterklassen überschrieben.
- Abstract Factory: Die Objekterzeugung erfolgt über ein Factory-Objekt, das mehrere Produkte einer Familie erzeugt.
Fazit
- Beide Muster helfen, die Erzeugung von Objekten zu kapseln und die Flexibilität des Codes zu erhöhen.
- Die Wahl des Musters hängt davon ab, ob einzelne Produkte oder Familien von Produkten erzeugt werden sollen.
- In C# bieten statische Factory-Methoden eine praktikable Lösung für die Erzeugung und Validierung von Domain-Objekten.