Clean Architecture och designmönster i praktiken · Lektion

Command- och Iterator-mönster

Inkapsla anrop som objekt med Command och gå igenom samlingar med Iterator.

Lektion 2 av 411 steg

Command- och Iterator-mönster är en gratis lektion i Clean Architecture och designmönster i praktiken på CoddyKit. Detta är lektion 2 av 4. Ni kan läsa hela lektionen gratis nedan och sedan öva praktiskt i webbläsaren med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt. Den ingår i lärvägen för Clean Architecture och designmönster i praktiken, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i Clean Architecture och designmönster i praktiken innehåller totalt 4 lektioner.

Vad är kommandomönstret?

Kommandomönstret är ett beteendemönster som omvandlar en begäran till ett fristående objekt. Objektet innehåller all information om begäran, inklusive vilken metod som ska anropas och vilka parametrar den behöver.

Tänk på det som att lägga en instruktion i ett paket. Ni kan sedan skicka runt paketet, placera det i en kö eller till och med ångra det senare, utan att avsändaren behöver känna till hur instruktionen utförs.

Kommandots centrala komponenter

För att förstå kommandomönstret tittar vi på dess viktigaste aktörer:

  • Command: Ett gränssnitt eller en abstrakt klass som deklarerar en execute()-metod.
  • ConcreteCommand: Implementerar gränssnittet Command och kopplar ett specifikt Receiver-objekt till en åtgärd.
  • Receiver: Objektet som utför det faktiska arbetet. Det vet hur operationen ska genomföras.
  • Invoker: Ber kommandot att utföra sin begäran. Det känner inte till detaljerna i operationen eller mottagaren.
  • Client: Skapar ett ConcreteCommand-objekt och anger dess Receiver.

Kommandomönstret i praktiken

Föreställ er ett smart hem-system där ni vill styra en lampa. Utan kommandomönstret skulle fjärrkontrollen direkt anropa light.turnOn() eller light.turnOff().

Med kommandomönstret vet fjärrkontrollen bara hur den ska ”utföra ett kommando”. Den bryr sig inte om kommandot tänder en lampa, öppnar en garageport eller spelar musik. Det gör fjärrkontrollen (Invoker) mycket flexibel!

Kod: kommando för att tända och släcka en lampa

Här är ett enkelt Java-exempel som visar kommandomönstret för styrning av en lampa. Lägg märke till hur RemoteControl (Invoker) endast interagerar med gränssnittet Command.

interface Command {
  void execute();
}

class Light {
  public void turnOn() {
    System.out.println("Light is ON");
  }
  public void turnOff() {
    System.out.println("Light is OFF");
  }
}

class LightOnCommand implements Command {
  private Light light;

  public LightOnCommand(Light light) {
    this.light = light;
  }

  @Override
  public void execute() {
    light.turnOn();
  }
}

class LightOffCommand implements Command {
  private Light light;

  public LightOffCommand(Light light) {
    this.light = light;
  }

  @Override
  public void execute() {
    light.turnOff();
  }
}

class RemoteControl {
  private Command command;

  public void setCommand(Command command) {
    this.command = command;
  }

  public void pressButton() {
    command.execute();
  }
}

public class Main {
  public static void main(String[] args) {
    Light livingRoomLight = new Light();

    LightOnCommand onCommand = new LightOnCommand(livingRoomLight);
    LightOffCommand offCommand = new LightOffCommand(livingRoomLight);

    RemoteControl remote = new RemoteControl();

    remote.setCommand(onCommand);
    remote.pressButton();

    remote.setCommand(offCommand);
    remote.pressButton();
  }
}

Fördelar med kommandomönstret

Kommandomönstret erbjuder flera kraftfulla fördelar:

  • Frikoppling: Invoker är frikopplad från Receiver, vilket minskar beroenden.
  • Ångra/gör om: Kommandon kan lagras i en historiklista, vilket gör det enklare att implementera funktioner för att ångra och göra om.
  • Köhantering/loggning: Begäranden kan placeras i kö, loggas och köras vid olika tidpunkter.
  • Utbyggbarhet: Nya kommandon kan läggas till utan att befintlig Invoker-kod behöver ändras.

Vad är iterator-mönstret?

Iterator-mönstret är ett beteendemönster som ger ett sätt att sekventiellt komma åt elementen i ett sammansatt objekt (till exempel en lista eller array) utan att exponera dess underliggande representation.

Föreställ er att ni har en spellista med låtar. En iterator gör det möjligt att gå igenom varje låt en i taget (nästa, föregående och så vidare) utan att ni behöver veta om spellistan lagras som en array, en länkad lista eller något helt annat.

Iteratorns centrala komponenter

Iterator-mönstret består av följande huvudkomponenter:

  • Iterator: Ett gränssnitt som definierar metoder för att komma åt och gå igenom element (t.ex. hasNext(), next()).
  • ConcreteIterator: Implementerar gränssnittet Iterator och håller reda på den aktuella positionen vid genomgången.
  • Aggregate: Ett gränssnitt eller en abstrakt klass som definierar en metod för att skapa ett Iterator-objekt (t.ex. createIterator()).
  • ConcreteAggregate: Implementerar gränssnittet Aggregate och returnerar en instans av ConcreteIterator.

Iterator-mönstret i praktiken

De flesta programmeringsspråk har inbyggda iteratorer (som Javas Iterator eller Pythons itererbara objekt). Ibland skapar ni dock en anpassad samling där ni behöver definiera er egen logik för genomgång.

Om ni till exempel har en anpassad klass MyStringList som internt lagrar strängar, kan en iterator låta extern kod gå igenom dessa strängar utan att känna till om MyStringList internt använder en array, en länkad lista eller en trädstruktur.

Kod: iterator för anpassad lista

Det här Java-exemplet visar hur ni skapar en anpassad StringList och en Iterator för den. Metoden Main kan gå igenom listan med hjälp av iteratorn utan att känna till dess interna array.

interface MyIterator {
  boolean hasNext();
  String next();
}

interface MyAggregate {
  MyIterator createIterator();
}

class MyStringList implements MyAggregate {
  private String[] items;
  private int count;

  public MyStringList(int capacity) {
    items = new String[capacity];
    count = 0;
  }

  public void add(String item) {
    if (count < items.length) {
      items[count++] = item;
    }
  }

  @Override
  public MyIterator createIterator() {
    return new StringListIterator(this);
  }

  // Helper to access elements by index for the iterator
  public String get(int index) {
    if (index >= 0 && index < count) {
      return items[index];
    }
    return null;
  }

  public int size() {
    return count;
  }
}

class StringListIterator implements MyIterator {
  private MyStringList list;
  private int position;

  public StringListIterator(MyStringList list) {
    this.list = list;
    this.position = 0;
  }

  @Override
  public boolean hasNext() {
    return position < list.size();
  }

  @Override
  public String next() {
    if (hasNext()) {
      return list.get(position++);
    }
    return null;
  }
}

public class Main {
  public static void main(String[] args) {
    MyStringList names = new MyStringList(5);
    names.add("Alice");
    names.add("Bob");
    names.add("Charlie");

    MyIterator iterator = names.createIterator();

    System.out.println("Iterating through names:");
    while (iterator.hasNext()) {
      System.out.println(iterator.next());
    }
  }
}

Snabbtest: designmönster

Ni har lärt er om två kraftfulla beteendemönster. Nu testar vi er förståelse.

Sammanfattning: Command och Iterator

Bra jobbat! I den här lektionen utforskade vi två viktiga beteendemönster:

  • Kommandomönstret kapslar in en begäran som ett objekt, vilket möjliggör kraftfulla funktioner som att ångra/göra om, köhantering och loggning av begäranden, samtidigt som Invoker frikopplas från Receiver.
  • Iterator-mönstret ger ett standardiserat sätt att gå igenom elementen i en samling, abstraherar bort samlingens interna struktur och främjar flexibla metoder för iteration.

Om ni behärskar dessa mönster förbättras flexibiliteten och underhållbarheten hos era programvarudesigner avsevärt.

Gratis att börja

Lär dig Clean Architecture och designmönster i praktiken med en AI-lärare – gratis

Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.

Kurser
12
Lektioner
48

Vanliga frågor

Är lektionen ”Command- och Iterator-mönster” gratis?

Ja – hela texten till ”Command- och Iterator-mönster” kan läsas gratis här på webben. Om Ni vill öva interaktivt med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt och låsa upp resten av kursen i Clean Architecture och designmönster i praktiken, kan Ni uppgradera till CoddyKit PRO. Kursen i Clean Architecture och designmönster i praktiken innehåller totalt 4 lektioner.

Vad lär jag mig i ”Command- och Iterator-mönster”?

Inkapsla anrop som objekt med Command och gå igenom samlingar med Iterator. Ni övar på Clean Architecture och designmönster i praktiken med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.

Behöver jag någon erfarenhet för att börja lära mig Clean Architecture och designmönster i praktiken?

Du behöver inga förkunskaper. Utbildningen i Clean Architecture och designmönster i praktiken på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 2 av 4.

Hur lång tid tar lektionen ”Command- och Iterator-mönster”?

De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.

Kan jag skriva och köra kod i den här Clean Architecture och designmönster i praktiken-lektionen?

Ja. Varje Clean Architecture och designmönster i praktiken-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.

Alla lektioner i den här kursen

  1. Observer- och Strategy-mönster
  2. Command- och Iterator-mönster
  3. Template Method- och State-mönster
  4. Mediator och Chain of Responsibility
← Tillbaka till Clean Architecture och designmönster i praktiken