Adapter- og Decorator-mønstre
Forstå, hvordan Adapter får inkompatible grænseflader til at fungere sammen, og hvordan Decorator tilføjer ansvar dynamisk.
Adapter- og Decorator-mønstre er en gratis Ren arkitektur og designmønstre i praksis-lektion på CoddyKit. Dette er lektion 1 af 4. Du kan læse hele lektionen gratis nedenfor — og derefter øve dig praktisk i browseren med en indbygget kodeeditor og en AI-vejleder, der er tilgængelig døgnet rundt. Den er en del af læringsforløbet i Ren arkitektur og designmønstre i praksis, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. Ren arkitektur og designmønstre i praksis-kurset indeholder 4 lektioner i alt.
Strukturelle mønstre: Forbind og udvid
Velkommen til strukturelle designmønstre! Disse mønstre hjælper dig med at sammensætte objekter og klasser i større strukturer, så systemerne bliver mere fleksible og effektive.
I denne lektion udforsker vi to effektive mønstre:
- Adapter-mønsteret: Får inkompatible interfaces til at fungere sammen.
- Decorator-mønsteret: Tilføjer nye funktioner til objekter dynamisk.
Udfordringen med inkompatibilitet
Forestil dig, at du har et eksisterende system, der forventer, at objekter opfører sig på en bestemt måde (via et bestemt interface). Nu skal du integrere en ny komponent, der udfører lignende arbejde, men har et andet interface.
Hvordan får du dem til at kommunikere uden at ændre det eksisterende system eller den nye komponent? Det er en almindelig udfordring inden for softwareudvikling.
Mød Adapter-mønsteret
Adapter-mønsteret fungerer som en bro mellem to inkompatible interfaces. Det konverterer interfacet fra én klasse til et andet interface, som klienterne forventer.
Tænk på en universal strømadapter: Den lader din enhed (klienten) slutte til enhver stikkontakt (den tilpassede komponent) ved at konvertere den fysiske forbindelse. Enheden er ligeglad med typen af stikkontakt, så længe den får strøm.
Roller i Adapter-mønsteret
Adapter-mønsteret består af tre centrale roller:
- Target: Det interface, som klienten forventer og bruger.
- Adaptee: Den eksisterende klasse med det inkompatible interface, der skal tilpasses.
- Adapter: Klassen, der implementerer Target-interfacet og omslutter en Adaptee-instans, så klientens anmodninger oversættes til kald til Adaptee.
Det gør det muligt for klienter at arbejde med forskellige klasser gennem ét ensartet interface.
Eksempel på Adapter-kode
Lad os se, hvordan en adapter kan få en moderne konsolskriver til at fungere sammen med et gammelt logningssystem.
Vores LegacyLogger forventer en logMessage-metode, men vores ModernConsoleWriter har writeToConsole.
ConsoleWriterAdapter bygger bro over denne forskel.
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.");
}
}Hvornår skal du bruge Adapter?
Overvej at bruge Adapter-mønsteret, når:
- Du vil bruge en eksisterende klasse, men dens interface ikke passer til det, du har brug for.
- Du vil oprette en genbrugelig klasse, der fungerer sammen med indbyrdes uafhængige eller uforudsete klasser, altså klasser, der ikke nødvendigvis har kompatible interfaces.
- Du integrerer en ny komponent eller et bibliotek i et eksisterende system med en fast API.
Decorator: Tilføj funktioner dynamisk
Nogle gange skal du tilføje nye ansvarsområder eller funktioner til et objekt uden at ændre dets oprindelige struktur eller påvirke andre objekter af samme klasse. Det er her, Decorator-mønsteret er særligt nyttigt.
Det giver dig mulighed for at omslutte objekter med ny funktionalitet, ligesom når du tilføjer toppings til en almindelig kaffe. Hver topping (decorator) tilføjer en ny pris og beskrivelse uden at ændre selve kaffen.
Roller i Decorator-mønsteret
Decorator-mønsteret består af:
- Component: Basisinterfacet for objekter, der kan dekoreres. Både konkrete komponenter og decorators implementerer dette.
- Concrete Component: Det grundlæggende objekt, som ansvarsområder kan tilføjes til.
- Decorator: En abstrakt klasse (eller et interface), der indeholder en reference til et Component-objekt og implementerer Component-interfacet.
- Concrete Decorators: Specifikke decorators, der tilføjer ny funktionalitet til komponenten.
Eksempel på Decorator-kode
Lad os se, hvordan du kan tilføje mælk og sukker til en enkel kaffe ved hjælp af decorators. Hver decorator omslutter det eksisterende kaffeobjekt og tilføjer sin egen logik.
Det giver fleksible kombinationer af udvidelser.
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());
}
}Hvornår skal du bruge Decorator?
Brug Decorator-mønsteret, når:
- Du skal tilføje ansvarsområder til individuelle objekter dynamisk og transparent uden at påvirke andre objekter.
- Du vil udvide et objekts funktionalitet uden at bruge nedarvning, som kan føre til en "eksplosion af underklasser" ved mange kombinationer.
- Du skal muliggøre fleksible kombinationer af ansvarsområder.
Hurtigt tjek: Mønsterets formål
Læs beskrivelserne nedenfor. Hvilken af dem identificerer korrekt det primære formål med Adapter-mønsteret?
Opsummering: Adapter og Decorator
Godt klaret! Du har nu lært to effektive strukturelle designmønstre:
- Adapter-mønsteret: Løser problemet med inkompatible interfaces, så eksisterende komponenter kan fungere problemfrit sammen. Det handler om at få ting til at passe sammen.
- Decorator-mønsteret: Løser problemet med dynamisk at tilføje nye ansvarsområder til objekter uden at ændre deres grundlæggende struktur. Det handler om at udvide funktionaliteten.
Disse mønstre giver fleksible måder at strukturere din kode på, så den bliver nemmere at vedligeholde og udvide. Bliv ved med at øve dig i dem!
Lær Ren arkitektur og designmønstre i praksis med en AI-underviser — gratis
Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.
- Kurser
- 12
- Lektioner
- 48
Ofte stillede spørgsmål
Er lektionen “Adapter- og Decorator-mønstre” gratis?
Ja — hele teksten til “Adapter- og Decorator-mønstre” kan læses gratis her på nettet. Hvis du vil øve dig interaktivt med en indbygget kodeeditor og en AI-vejleder døgnet rundt og få adgang til resten af Ren arkitektur og designmønstre i praksis-kurset, skal du opgradere til CoddyKit PRO. Ren arkitektur og designmønstre i praksis-kurset indeholder 4 lektioner i alt.
Hvad lærer jeg i “Adapter- og Decorator-mønstre”?
Forstå, hvordan Adapter får inkompatible grænseflader til at fungere sammen, og hvordan Decorator tilføjer ansvar dynamisk. Du øver dig i Ren arkitektur og designmønstre i praksis med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.
Skal jeg have erfaring for at begynde på Ren arkitektur og designmønstre i praksis?
Der kræves ingen tidligere erfaring. Ren arkitektur og designmønstre i praksis på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 1 af 4.
Hvor lang tid tager lektionen “Adapter- og Decorator-mønstre”?
De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.
Kan jeg skrive og køre kode i denne Ren arkitektur og designmønstre i praksis-lektion?
Ja. Alle Ren arkitektur og designmønstre i praksis-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.
Alle lektioner i dette kursus
- Adapter- og Decorator-mønstre
- Facade- og Proxy-mønstre
- Composite- og Bridge-mønstre
- Flyweight pattern til effektiv hukommelsesbrug