Adapter- und Decorator-Muster
Verstehen Sie, wie Adapter inkompatible Schnittstellen zusammenarbeiten lässt und Decorator Verantwortlichkeiten dynamisch hinzufügt.
Adapter- und Decorator-Muster ist eine kostenlose Clean Architecture & Design Patterns in Practice-Lektion auf CoddyKit. Dies ist Lektion 1 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des Clean Architecture & Design Patterns in Practice-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der Clean Architecture & Design Patterns in Practice-Kurs umfasst insgesamt 4 Lektionen.
Teile dieser Lektion wurden noch nicht übersetzt und werden auf Englisch angezeigt.
Structural Patterns: Connect & Enhance
Willkommen bei den Strukturmustern (Structural Design Patterns)! Diese Entwurfsmuster helfen Ihnen dabei, Objekte und Klassen zu größeren Strukturen zusammenzufügen, wodurch Systeme flexibler und effizienter werden.
In dieser Lektion werden wir zwei leistungsstarke Muster untersuchen:
- Adapter-Muster: Damit inkompatible Schnittstellen zusammenarbeiten können.
- Decorator-Muster (Dekorierer-Muster): Um Objekten dynamisch neue Funktionalitäten hinzuzufügen.
The Incompatibility Challenge
Stellen Sie sich vor, Sie haben ein bestehendes System, das von Objekten ein bestimmtes Verhalten (eine bestimmte Schnittstelle) erwartet. Nun müssen Sie eine neue Komponente integrieren, die ähnliche Arbeit leistet, aber eine andere Schnittstelle hat.
Wie bringen Sie diese dazu, miteinander zu kommunizieren, ohne das bestehende System oder die neue Komponente zu verändern? Dies ist eine häufige Herausforderung in der Softwareentwicklung.
Meet the Adapter Pattern
Das Adapter-Muster fungiert als Brücke zwischen zwei inkompatiblen Schnittstellen. Es konvertiert die Schnittstelle einer Klasse in eine andere Schnittstelle, die von Clients erwartet wird.
Man stelle sich einen universellen Reiseadapter vor: Er ermöglicht es Ihrem Gerät (Client), sich an jede Steckdose (Adaptee) anzuschließen, indem er die physische Verbindung anpasst. Dem Gerät ist der Steckdossentyp egal, Hauptschutz es erhält Strom.
Roles in the Adapter Pattern
Das Adapter-Pattern umfasst drei Hauptrollen:
- Target (Ziel): Die Schnittstelle, die der Client erwartet und verwendet.
- Adaptee (Anzupassende Klasse): Die bestehende Klasse mit der inkompatiblen Schnittstelle, die angepasst werden muss.
- Adapter: Die Klasse, die die Target-Schnittstelle implementiert und eine Adaptee-Instanz umschließt, wobei sie Client-Anfragen in Aufrufe des Adaptee übersetzt.
Es ermöglicht Clients, mit verschiedenen Klassen über eine einzige, einheitliche Schnittstelle zu arbeiten.
Adapter Code Example
Sehen wir uns an, wie ein Adapter einen modernen Konsolenschreiber mit einem alten Protokollierungssystem kompatibel machen kann.
Unser LegacyLogger erwartet eine logMessage-Methode, aber unser ModernConsoleWriter verfügt über writeToConsole.
Der ConsoleWriterAdapter überbrückt diese Kluft.
interface LegacyLogger {
void logMessage(String message);
}
class ModernConsoleWriter {
public void writeToConsole(String text) {
System.out.println("Console: " + text);
}
}
class ConsoleWriterAdapter implements LegacyLogger {
private ModernConsoleWriter adaptee;
public ConsoleWriterAdapter(ModernConsoleWriter adaptee) {
this.adaptee = adaptee;
}
@Override
public void logMessage(String message) {
adaptee.writeToConsole("[LEGACY] " + message);
}
}
public class Main {
public static void main(String[] args) {
ModernConsoleWriter writer = new ModernConsoleWriter();
LegacyLogger logger = new ConsoleWriterAdapter(writer);
System.out.println("Using the adapter:");
logger.logMessage("This is an old log entry.");
System.out.println("\nUsing the original writer directly:");
writer.writeToConsole("This is a modern console output.");
}
}When to Apply Adapter
Erwägen Sie die Verwendung des Adapter-Musters, wenn:
- Sie eine bestehende Klasse verwenden möchten, deren Schnittstelle jedoch nicht Ihren Anforderungen entspricht.
- Sie eine wiederverwendbare Klasse erstellen möchten, die mit nicht zusammenhängenden oder unvorhergesehenen Klassen zusammenarbeitet, d. h. mit Klassen, die nicht unbedingt über kompatible Schnittstellen verfügen.
- Sie eine neue Komponente oder Bibliothek in ein bestehendes System mit einer festen API integrieren.
Decorator: Adding Features Dynamically
Manchmal müssen Sie einem Objekt neue Verantwortlichkeiten oder Verhaltensweisen hinzufügen, ohne seine ursprüngliche Struktur zu verändern oder andere Objekte derselben Klasse zu beeinflussen. Hier glänzt das Decorator-Pattern (Dekorierer-Muster).
Es ermöglicht Ihnen, Objekte mit neuer Funktionalität zu umhüllen, wie das Hinzufügen von Toppings zu einem Grundkaffee. Jedes Topping (Dekorierer) fügt neue Kosten und eine Beschreibung hinzu, ohne den Kaffee selbst zu verändern.
Roles in the Decorator Pattern
The Decorator Pattern involves:
- Component: The base interface for objects that can be decorated. Both concrete components and decorators implement this.
- Concrete Component: The basic object to which responsibilities can be added.
- Decorator: An abstract class (or interface) that maintains a reference to a Component object and implements the Component interface.
- Concrete Decorators: Specific decorators that add new functionalities to the component.
Decorator Code Example
Let's see how to add milk and sugar to a simple coffee using decorators. Each decorator wraps the existing coffee object and adds its own logic.
This allows for flexible combinations of enhancements.
interface Coffee {
double getCost();
String getDescription();
}
class SimpleCoffee implements Coffee {
@Override
public double getCost() {
return 2.0;
}
@Override
public String getDescription() {
return "Simple Coffee";
}
}
abstract class CoffeeDecorator implements Coffee {
protected Coffee decoratedCoffee;
public CoffeeDecorator(Coffee coffee) {
this.decoratedCoffee = coffee;
}
@Override
public double getCost() {
return decoratedCoffee.getCost();
}
@Override
public String getDescription() {
return decoratedCoffee.getDescription();
}
}
class MilkDecorator extends CoffeeDecorator {
public MilkDecorator(Coffee coffee) {
super(coffee);
}
@Override
public double getCost() {
return super.getCost() + 0.5;
}
@Override
public String getDescription() {
return super.getDescription() + ", Milk";
}
}
class SugarDecorator extends CoffeeDecorator {
public SugarDecorator(Coffee coffee) {
super(coffee);
}
@Override
public double getCost() {
return super.getCost() + 0.2;
}
@Override
public String getDescription() {
return super.getDescription() + ", Sugar";
}
}
public class Main {
public static void main(String[] args) {
Coffee myCoffee = new SimpleCoffee();
System.out.println(myCoffee.getDescription() + " $" + myCoffee.getCost());
myCoffee = new MilkDecorator(myCoffee);
System.out.println(myCoffee.getDescription() + " $" + myCoffee.getCost());
myCoffee = new SugarDecorator(myCoffee);
System.out.println(myCoffee.getDescription() + " $" + myCoffee.getCost());
Coffee anotherCoffee = new SugarDecorator(new MilkDecorator(new SimpleCoffee()));
System.out.println(anotherCoffee.getDescription() + " $" + anotherCoffee.getCost());
}
}When to Apply Decorator
Use the Decorator Pattern when:
- You need to add responsibilities to individual objects dynamically and transparently, without affecting other objects.
- You want to extend an object's functionality without using subclassing, which can lead to a "subclass explosion" for many combinations.
- You need to allow for flexible combinations of responsibilities.
Quick Check: Pattern Purpose
Read the descriptions below. Which one correctly identifies the primary purpose of the Adapter Pattern?
Recap: Adapter & Decorator
Great job! You've now learned two powerful structural design patterns:
- Adapter Pattern: Solves the problem of incompatible interfaces, allowing existing components to work together seamlessly. It's about 'making things fit'.
- Decorator Pattern: Solves the problem of adding new responsibilities to objects dynamically, without altering their core structure. It's about 'enhancing functionality'.
These patterns provide flexible ways to structure your code, making it more maintainable and extensible. Keep practicing them!
Häufig gestellte Fragen
Ist die Lektion „Adapter- und Decorator-Muster“ kostenlos?
Ja — der vollständige Text von „Adapter- und Decorator-Muster“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des Clean Architecture & Design Patterns in Practice-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der Clean Architecture & Design Patterns in Practice-Kurs umfasst insgesamt 4 Lektionen.
Was lerne ich in „Adapter- und Decorator-Muster“?
Verstehen Sie, wie Adapter inkompatible Schnittstellen zusammenarbeiten lässt und Decorator Verantwortlichkeiten dynamisch hinzufügt. Du übst Clean Architecture & Design Patterns in Practice mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.
Brauche ich Erfahrung, um Clean Architecture & Design Patterns in Practice zu starten?
Keine Vorkenntnisse erforderlich. Clean Architecture & Design Patterns in Practice auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 1 von 4.
Wie lange dauert die Lektion „Adapter- und Decorator-Muster“?
Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.
Kann ich in dieser Clean Architecture & Design Patterns in Practice-Lektion Code schreiben und ausführen?
Ja. Jede Clean Architecture & Design Patterns in Practice-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.
Alle Lektionen in diesem Kurs
- Adapter- und Decorator-Muster
- Facade- und Proxy-Muster
- Composite- und Bridge-Muster
- Das Flyweight Pattern für effiziente Speichernutzung