Come usare il modello di progettazione dei comandi in C #

I modelli di progettazione sono soluzioni collaudate utilizzate per risolvere problemi di progettazione comuni e ridurre le complessità nel codice. I modelli di design Gang of Four si dividono in tre categorie:

  • Creazionale - modelli relativi alla creazione di oggetti
  • Strutturale: modelli relativi all'assemblaggio di oggetti
  • Comportamentali: modelli relativi alla collaborazione con gli oggetti e alla separazione delle responsabilità

Il modello di progettazione del comando rientra nella categoria del modello comportamentale. Questo articolo esplora come possiamo lavorare con il modello di progettazione dei comandi in C #.

Qual è il modello di progettazione del comando?

Lo scopo del modello di progettazione del comando è disaccoppiare il richiedente di un'azione dall'oggetto che esegue l'azione. Nel modello di progettazione del comando, una richiesta è incapsulata come un oggetto che contiene tutte le informazioni sulla richiesta. Questo oggetto viene quindi passato a un oggetto invoker. L'oggetto invoker cerca quindi l'oggetto appropriato per gestire il comando e passa il comando all'oggetto.

Il modello di progettazione dei comandi è una buona scelta quando si desidera implementare callback, attività di accodamento, tracciamento della cronologia e funzionalità di annullamento / ripristino nell'applicazione. Il modello di comando è una buona scelta per implementare i meccanismi di ripetizione dei tentativi, quando l'applicazione desidera ritentare la connessione a un servizio in un momento successivo che non è attivo e in esecuzione in questo momento. Il modello di comando viene utilizzato anche nelle applicazioni di accodamento dei messaggi, ovvero nelle applicazioni che devono essere ripristinate dalla perdita di dati.

Partecipanti al modello di progettazione del comando

In un'implementazione classica del modello di comando hai quattro componenti: il comando, l'invocatore, il destinatario e il client. I partecipanti al modello di progettazione del comando includono quanto segue:

  • Comando: fornisce un'interfaccia per eseguire un'operazione
  • ConcreteCommand: estende l'interfaccia di comando e implementa il metodo Execute
  • Client: crea un'istanza di una classe ConcreteCommand
  • Invoker: informa il comando per eseguire la richiesta
  • Destinatario: contiene la logica per eseguire le operazioni associate alla richiesta

Esempio di modello di progettazione dei comandi in C #

Nella prossima sezione esploreremo come implementare il modello di progettazione dei comandi. Nel nostro esempio, implementeremo una semplice calcolatrice utilizzando le seguenti classi:

  • Comando (classe base astratta di comando)
  • SimpleCalculator (classe ricevitore)
  • AddCommand (classe di comando concreta)
  • SubstractCommand (classe di comando concreta)
  • Multiply Command (classe di comando concreta)
  • DivideCommand (classe di comando concreta)
  • Invoker (classe Invoker)

Creare la classe base astratta Command in C #

Considera la seguente classe base astratta denominata Command che contiene la dichiarazione del metodo Execute.

public abstract class Comando

    {

        ricevitore SimpleCalculator protetto;

        public Command (ricevitore SimpleCalculator)

        {

            this.receiver = receiver;

        }

        abstract pubblico int Execute ();

    }

L'enumerazione seguente mostra le operazioni che saranno supportate nella nostra semplice calcolatrice.

public enum CommandOption

    {

        Aggiungi, Sottrai, Moltiplica, Dividi

    }

Creare la classe ricevitore in C #

La seguente è una classe denominata SimpleCalculator. Questa classe funge da ricevitore e contiene la definizione dei metodi Add, Subtract, Multiply e Divide.

classe pubblica SimpleCalculator

    {

        private int _x, _y;

        public SimpleCalculator (int a, int b)

        {

            _x = a;

            _y = b;

        }

        public int Aggiungi ()

        {

            return _x + _y;

        }

        public int Sottrai ()

        {

            return _x - _y;

        }

        public int Moltiplica ()

        {

            return _x * _y;

        }

        public int Divide ()

        {

            return _x / _y;

        }

    }

Crea le classi di comando concrete in C #

Le classi di comando concrete estendono la classe base astratta Command e implementano il metodo Execute come mostrato di seguito.

 classe pubblica AddCommand: Command

    {

        private SimpleCalculator _calculator;

        public AddCommand (calcolatrice SimpleCalculator): base (calcolatrice)

        {

            _calculator = calcolatrice;

        }

        public override int Execute ()

        {

            return _calculator.Add ();

        }

    }

    classe pubblica SubtractCommand: Command

    {

        private SimpleCalculator _calculator;

        public SubtractCommand (calcolatrice SimpleCalculator):

        base (calcolatrice)

        {

            _calculator = calcolatrice;

        }

        public override int Execute ()

        {

            return _calculator.Subtract ();

        }

    }

    public class MultiplyCommand: Command

    {

        private SimpleCalculator _calculator;

        public MultiplyCommand (calcolatrice SimpleCalculator):

        base (calcolatrice)

        {

            _calculator = calcolatrice;

        }

        public override int Execute ()

        {

            return _calculator.Multiply ();

        }

    }

    public class DivideCommand: Command

    {

        private SimpleCalculator _calculator;

        public DivideCommand (calcolatrice SimpleCalculator):

        base (calcolatrice)

        {

            _calculator = calcolatrice;

        }

        public override int Execute ()

        {

            return _calculator.Divide ();

        }

    }

Crea la classe Invoker in C #

Il frammento di codice seguente illustra la classe Invoker. Contiene due metodi, SetCommand ed Execute. Mentre SetCommand viene utilizzato per assegnare l'oggetto command al riferimento Command privato nella classe Invoker, Execute viene utilizzato per eseguire il comando.

    Invoker della classe pubblica

    {

        Comando privato _command;

        public void SetCommand (comando comando)

        {

            _command = comando;

        }

        public int Esegui ()

        {

            return _command.Execute ();

        }

    }

Il modello di progettazione dei comandi in azione in C #

Infine, il frammento di codice seguente illustra come eseguire un semplice calcolo utilizzando la classe SimpleCalculator.

static void Main (string [] args)

        {

            Calcolatrice SimpleCalculator = nuovo SimpleCalculator (15, 3);

            var addCommand = new AddCommand (calcolatrice);

            var substractCommand = new SubtractCommand (calcolatrice);

            var multiplyCommand = new MultiplyCommand (calcolatrice);

            var divideCommand = new DivideCommand (calcolatrice);

            Invoker invoker = new Invoker ();

            invoker.SetCommand (addCommand);

            Console.WriteLine ("Il risultato è {0}", invoker.Execute ());

            invoker.SetCommand (substractCommand);

            Console.WriteLine ("Il risultato è {0}", invoker.Execute ());

            invoker.SetCommand (multiplyCommand);

            Console.WriteLine ("Il risultato è {0}", invoker.Execute ());

            invoker.SetCommand (divideCommand);

            Console.WriteLine ("Il risultato è {0}", invoker.Execute ());

            Console.ReadLine ();

        }

Il modello di progettazione del comando fornisce il supporto per l'estensibilità e riduce l'accoppiamento esistente tra il richiamo e il destinatario di un comando. Poiché la richiesta è incapsulata in un oggetto autonomo, è possibile parametrizzare metodi con richieste diverse, salvare richieste in una coda e persino fornire supporto per operazioni ripetibili o annullabili.

-

Fai di più con C #:

  • Come lavorare con AutoMapper in C #
  • Quando usare una classe astratta e un'interfaccia in C #
  • Come lavorare con i thread in C #
  • Come utilizzare Dapper ORM in C #
  • Come implementare il modello di progettazione del repository in C #
  • Come implementare un semplice logger in C #
  • Come lavorare con i delegati in C #
  • Come lavorare con i delegati Action, Func e Predicate in C #
  • Come lavorare con log4net in C #
  • Come lavorare con la riflessione in C #