Menu
Coddy logo textTech

Pattern del Comando

Fa parte della sezione Programmazione orientata agli oggetti del percorso C# di Coddy. Lezione 56 di 70.

Il pattern Command è un pattern comportamentale che trasforma una richiesta in un oggetto autonomo contenente tutte le informazioni sulla richiesta. Questa trasformazione ti consente di passare le richieste come argomenti dei metodi, metterle in coda, registrarle o supportare operazioni annullabili.

Il pattern separa l'oggetto che invoca un'operazione dall'oggetto che sa come eseguirla. È composto da quattro componenti fondamentali: un'interfaccia di comando, comandi concreti, un ricevitore (l'oggetto che svolge il lavoro vero e proprio) e un invocatore (l'oggetto che attiva i comandi).

public interface ICommand
{
    void Execute();
}

public class Light  // Ricevitore
{
    public void TurnOn() => Console.WriteLine("Light is ON");
    public void TurnOff() => Console.WriteLine("Light is OFF");
}

public class TurnOnCommand : ICommand
{
    private Light _light;
    
    public TurnOnCommand(Light light) => _light = light;
    
    public void Execute() => _light.TurnOn();
}

public class TurnOffCommand : ICommand
{
    private Light _light;
    
    public TurnOffCommand(Light light) => _light = light;
    
    public void Execute() => _light.TurnOff();
}

L'invocatore memorizza ed esegue i comandi senza sapere cosa fanno:

public class RemoteControl  // Invocatore
{
    private ICommand _command;
    
    public void SetCommand(ICommand command) => _command = command;
    
    public void PressButton() => _command.Execute();
}

// Utilizzo
var light = new Light();
var remote = new RemoteControl();

remote.SetCommand(new TurnOnCommand(light));
remote.PressButton();  // Light è ON

remote.SetCommand(new TurnOffCommand(light));
remote.PressButton();  // Light è OFF

Il pattern Command è particolarmente utile per implementare la funzionalità di annullamento, registrare macro o accodare operazioni per eseguirle in un secondo momento. Ogni comando incapsula tutto ciò che serve per eseguire un’azione, rendendo il tuo sistema più flessibile ed estensibile.

challenge icon

Sfida

Facile

Creiamo un sistema di comandi per un editor di testo usando il pattern Command. Creerai un sistema in cui le operazioni di modifica, come l’inserimento e l’eliminazione di testo, sono incapsulate in oggetti comando, consentendo all’editor di eseguirle tramite un’interfaccia unificata.

Organizzerai il codice in tre file:

  • Command.cs: Definisci un’interfaccia ICommand nello spazio dei nomi TextEditor con un solo metodo Execute(). Poi crea due classi comando concrete:
    • InsertCommand - accetta un Document e una stringa text nel costruttore. Quando viene eseguito, aggiunge il testo al documento e stampa Inserted: {text}
    • DeleteCommand - accetta un Document e un int count nel costruttore. Quando viene eseguito, rimuove dal documento gli ultimi count caratteri e stampa Deleted: {count} characters
  • Document.cs: Crea una classe Document nello stesso spazio dei nomi. Questo è il ricevitore: l’oggetto che esegue effettivamente le operazioni sul testo. Dovrebbe avere:
    • Un campo stringa privato per memorizzare il contenuto (inizializzato come stringa vuota)
    • Un metodo Append(string text) che aggiunge testo al contenuto
    • Un metodo RemoveLast(int count) che rimuove gli ultimi count caratteri (se count supera la lunghezza del contenuto, cancella tutto il contenuto)
    • Un metodo GetContent() che restituisce il contenuto corrente
  • Program.cs: Crea una classe Editor che funge da invocatore. Dovrebbe avere un metodo SetCommand(ICommand command) e un metodo ExecuteCommand() che esegue il comando corrente. Nel codice principale, mostra il pattern Command elaborando una serie di operazioni di modifica.

Riceverai i seguenti input:

  • Numero di comandi da eseguire
  • Per ogni comando: il tipo di comando (insert o delete) seguito dal testo da inserire oppure dal numero di caratteri da eliminare

Dopo aver eseguito tutti i comandi, stampa il contenuto finale del documento su una nuova riga nel formato Content: {content}.

Per esempio, se gli input sono:

4
insert
Hello
insert
 World
delete
3
insert
!

L’output dovrebbe essere:

Inserted: Hello
Inserted:  World
Deleted: 3 characters
Inserted: !
Content: Hello Wo!

Nota che Editor (l’invocatore) non sa nulla della manipolazione del testo: si limita a eseguire qualsiasi comando gli venga assegnato. I comandi incapsulano sia l’azione sia il ricevitore, rendendo facile aggiungere nuove operazioni come ReplaceCommand senza modificare l’editor!

Provalo tu

using System;
using TextEditor;

// TODO: Crea la classe Editor (l'invocatore)
public class Editor
{
    // TODO: Aggiungi un campo privato per memorizzare il comando corrente
    private ICommand _command;

    // TODO: Implementa il metodo SetCommand
    public void SetCommand(ICommand command)
    {
        // TODO: Memorizza il comando
    }

    // TODO: Implementa il metodo ExecuteCommand
    public void ExecuteCommand()
    {
        // TODO: Esegui il comando corrente
    }
}

class Program
{
    public static void Main(string[] args)
    {
        // Leggi il numero di comandi
        int n = Convert.ToInt32(Console.ReadLine());

        // Crea il documento (il ricevitore)
        Document document = new Document();

        // Crea l'editor (l'invocatore)
        Editor editor = new Editor();

        // TODO: Elabora ogni comando
        for (int i = 0; i < n; i++)
        {
            string commandType = Console.ReadLine();

            // TODO: In base a commandType, crea il comando appropriato
            // - Se "insert": leggi il testo e crea InsertCommand
            // - Se "delete": leggi il numero e crea DeleteCommand
            // Poi imposta il comando nell'editor ed eseguilo
        }

        // TODO: Stampa il contenuto finale nel formato "Content: {content}"
    }
}
quiz iconMettiti alla prova

Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.

Tutte le lezioni di Programmazione orientata agli oggetti

Esercitati da solo: Compilatore C# online