Designmønstre er velprøvde løsninger som brukes til å løse vanlige designproblemer og redusere kompleksiteten i koden. Gang of Four designmønstre faller i tre kategorier:
- Creational - mønstre relatert til objektopprettelse
- Strukturelle - mønstre relatert til gjenstandssamling
- Atferdsmønstre - relatert til objektsamarbeid og ansvarsdeling
Kommando design mønsteret faller inn under atferdsmønster kategorien. Denne artikkelen utforsker hvordan vi kan jobbe med kommando-designmønsteret i C #.
Hva er kommando design mønster?
Hensikten med kommandodesignmønsteret er å koble rekvirenten av en handling fra objektet som utfører handlingen. I kommandodesignmønsteret er en forespørsel innkapslet som et objekt som inneholder all informasjon om forespørselen. Dette objektet blir deretter overført til et invoker-objekt. Invoker-objektet ser deretter etter riktig objekt for å håndtere kommandoen og overfører kommandoen til objektet.
Kommando-designmønsteret er et godt valg når du vil implementere tilbakeringinger, køoppgaver, sporingshistorikk og angre / gjenta funksjonalitet i applikasjonen din. Kommandomønsteret er et godt valg for å implementere prøvemekanismer - når søknaden din vil prøve å koble til en tjeneste på et senere tidspunkt som ikke er i gang for øyeblikket. Kommandomønsteret brukes også i applikasjoner som står i kø, dvs. i applikasjoner som trenger å gjenopprette fra tap av data.
Deltakere med kommandomønster
I en klassisk implementering av kommandomønsteret har du fire komponenter: kommandoen, innkalleren, mottakeren og klienten. Deltakerne i kommando-designmønsteret inkluderer følgende:
- Kommando - gir et grensesnitt for å utføre en operasjon
- ConcreteCommand - utvider Command-grensesnittet og implementerer Execute-metoden
- Client - starter en ConcreteCommand-klasse
- Invoker - informerer kommandoen om å utføre forespørselen
- Mottaker - inneholder logikken for å utføre operasjonene knyttet til forespørselen
Eksempel på kommando design mønster i C #
I neste avsnitt vil vi utforske hvordan vi kan implementere kommandodesignmønsteret. I vårt eksempel vil vi implementere en enkel kalkulator ved hjelp av følgende klasser:
- Command (Command abstract base class)
- SimpleCalculator (mottakerklasse)
- AddCommand (konkret kommandoklasse)
- SubstractCommand (konkret kommandoklasse)
- Multiply Command (konkret kommandoklasse)
- DivideCommand (konkret kommandoklasse)
- Invoker (Invoker-klasse)
Opprett kommandabstrakt basisklasse i C #
Tenk på følgende abstrakte basisklasse med navnet Command som inneholder erklæringen om Execute-metoden.
offentlig abstrakt klasse Kommando{
beskyttet SimpleCalculator mottaker;
offentlig kommando (SimpleCalculator mottaker)
{
this.receiver = mottaker;
}
offentlig abstrakt int Utfør ();
}
Følgende enum viser operasjonene som vil bli støttet i vår enkle kalkulator.
offentlig enum CommandOption{
Legg til, subtraher, multipliser, del
}
Opprett mottakerklassen i C #
Følgende er en klasse som heter SimpleCalculator. Denne klassen fungerer som mottaker og inneholder definisjonen av metodene Add, Subtraher, Multiply og Divide.
offentlig klasse SimpleCalculator{
privat int _x, _y;
offentlig SimpleCalculator (int a, int b)
{
_x = a;
_y = b;
}
public int Legg til ()
{
returnere _x + _y;
}
offentlig int trekke ()
{
returnere _x - _y;
}
public int Multipliser ()
{
returnere _x * _y;
}
offentlig int Divide ()
{
returnere _x / _y;
}
}
Lag de konkrete kommandoklassene i C #
De konkrete kommandoklassene utvider Command abstract-klassen og implementerer Execute-metoden som vist nedenfor.
offentlig klasse AddCommand: Kommando{
private SimpleCalculator _calculator;
offentlig AddCommand (SimpleCalculator kalkulator): base (kalkulator)
{
_calculator = kalkulator;
}
public override int Execute ()
{
returnere _calculator.Add ();
}
}
offentlig klasse SubtractCommand: Kommando
{
private SimpleCalculator _calculator;
public SubtractCommand (SimpleCalculator calculator):
base (kalkulator)
{
_calculator = kalkulator;
}
public override int Execute ()
{
return _calculator.Subtract ();
}
}
offentlig klasse MultiplyCommand: Kommando
{
private SimpleCalculator _calculator;
offentlig MultiplyCommand (SimpleCalculator-kalkulator):
base (kalkulator)
{
_calculator = kalkulator;
}
public override int Execute ()
{
returnere _calculator.Multiply ();
}
}
offentlig klasse DivideCommand: Kommando
{
private SimpleCalculator _calculator;
offentlig DivideCommand (SimpleCalculator kalkulator):
base (kalkulator)
{
_calculator = kalkulator;
}
public override int Execute ()
{
return _calculator.Divide ();
}
}
Lag Invoker-klassen i C #
Følgende kodebit illustrerer Invoker-klassen. Den inneholder to metoder, SetCommand og Execute. Mens SetCommand brukes til å tilordne kommandoobjektet til den private kommandoreferansen i Invoker-klassen, brukes Execute til å utføre kommandoen.
offentlig klasse Invoker{
privat kommando _kommando;
offentlig ugyldig SetCommand (kommandokommando)
{
_kommando = kommando;
}
public int Utfør ()
{
returnere _command.Execute ();
}
}
Kommando design mønster i aksjon i C #
Til slutt illustrerer følgende kodebit hvordan du kan utføre en enkel beregning ved hjelp av SimpleCalculator-klassen.
statisk tomrom Main (streng [] args){
SimpleCalculator kalkulator = ny SimpleCalculator (15, 3);
var addCommand = ny AddCommand (kalkulator);
var substractCommand = ny SubtractCommand (kalkulator);
var multiplyCommand = ny MultiplyCommand (kalkulator);
var divideCommand = ny DivideCommand (kalkulator);
Invoker invoker = ny Invoker ();
invoker.SetCommand (addCommand);
Console.WriteLine ("Resultatet er {0}", invoker.Execute ());
invoker.SetCommand (substractCommand);
Console.WriteLine ("Resultatet er {0}", invoker.Execute ());
invoker.SetCommand (multiplyCommand);
Console.WriteLine ("Resultatet er {0}", invoker.Execute ());
invoker.SetCommand (divideCommand);
Console.WriteLine ("Resultatet er {0}", invoker.Execute ());
Console.ReadLine ();
}
Kommando design mønsteret gir støtte for utvidbarhet og reduserer koblingen som eksisterer mellom påkaller og mottaker av en kommando. Siden forespørselen er innkapslet i et frittstående objekt, kan du parametrisere metoder med forskjellige forespørsler, lagre forespørsler i en kø, og til og med gi støtte for operasjoner som kan gjøres om eller angre.
—
Gjør mer med C #:
- Hvordan jobbe med AutoMapper i C #
- Når skal jeg bruke en abstrakt klasse vs. grensesnitt i C #
- Hvordan jobbe med tråder i C #
- Hvordan bruke Dapper ORM i C #
- Slik implementerer du mønsteret for depotdesign i C #
- Slik implementerer du en enkel logger i C #
- Hvordan jobbe med delegater i C #
- Hvordan jobbe med Action-, Func- og Predicate-delegater i C #
- Hvordan jobbe med log4net i C #
- Hvordan jobbe med refleksjon i C #