Na een paar creatieve en structurele ontwerppatronen te hebben behandeld, zijn we nu gedragspatronen gestart. U kunt het eerste artikel in deze categorie van het strategiepatroon zien. Met creativeringspatronen hebben we geleerd hoe we onze objecten moeten maken en uit structurele patronen hebben we geleerd hoe we onze klassen en objecten moeten structureren om een betere toepassing te helpen bouwen.
In dit artikel gaan we door het patroon van het opdrachtontwerp. Zoals de naam al zegt, zullen we in dit patroon te maken krijgen met het uitvoeren van verschillende commando's. Laat me een woord over dit patroon van Wikipedia nemen:
Het opdrachtpatroon is een gedragsontwerppatroon waarin een object wordt gebruikt om alle informatie weer te geven en in te kapselen die nodig is om een methode op een later tijdstip aan te roepen. Deze informatie omvat de naam van de methode, het object dat eigenaar is van de methode en waarden voor de parameters van de methode.
In principe heeft een patroon verschillende elementen, zoals hieronder. In de volgende sectie zullen we elk element onderzoeken met een codevoorbeeld. Ik zal het voorbeeld van radio-acties nemen - heel basale acties zouden de radio aan of uit zetten. Laten we dus elk element induiken.
Dit element bevat de daadwerkelijke implementatie (weet hoe de gevraagde opdracht moet worden uitgevoerd) van alle opdrachten. Dit handhaaft ook de geschiedenis van uitgevoerde opdrachten, maar maakt geen deel uit van het werkelijke opdrachtpatroon. We zullen dat deel in het Memento-ontwerppatroon zien.
// Receiver class radioControl openbare functie inschakelenOn () // Radio-echo inschakelen "Radio inschakelen"; openbare functie turnOff () // Radio-echo uitschakelen "Radio uitschakelen";
Dit element bevat informatie over de noodzakelijke actie die moet worden ondernomen. Het roept de vereiste methode uit ontvanger
.
// Command interface radio Command public function execute (); class turnOnRadio implementeert radioCommand private $ radioControl; openbare functie __construct (radioControl $ radioControl) $ this-> radioControl = $ radioControl; public function execute () $ this-> radioControl-> turnOn (); class turnOffRadio implementeert radioCommand private $ radioControl; openbare functie __construct (radioControl $ radioControl) $ this-> radioControl = $ radioControl; public function execute () $ this-> radioControl-> turnOff ();
Dit element gedraagt zich echt als een klant (besluit wat te doen). Het is zijn taak om te bepalen welk commando moet worden uitgevoerd, zonder te weten wie het zal uitvoeren en hoe het zal worden uitgevoerd. In dit voorbeeld heb ik het commando genomen als een hard-gecodeerde waarde, maar het kan overal vandaan worden gepakt, zoals een waarde van een URL en / of een postvariabele.
// Client $ in = 'turnOffRadio';
Dit element initieert het hele proces. Het neemt argumenten van de cliënt en roept het proces op om de vereiste opdracht aan te roepen.
// Invoker als (class_exists ($ in)) $ command = new $ in (new radioControl ()); else throw new Exception ('... Command Not Found ...'); $ command-> execute ();
Nadat we deze opdracht hebben uitgevoerd, wordt "Uitschakelen van radio" als uitvoer weergegeven, omdat de client die opdracht heeft aangeroepen. Aanvullende opdrachten kunnen op dezelfde manier worden uitgevoerd. Als onze actie was ingesteld zoals turnOffRadio
, dan moet het "Inschakelen Radio" tonen. Eenvoudig genoeg, is het niet?
Laten we alle elementen hier inpakken om te zien hoe het werkt.
// Receiver class radioControl openbare functie inschakelenOn () // Radio-echo inschakelen "Radio inschakelen"; openbare functie turnOff () // Radio-echo uitschakelen "Radio uitschakelen"; // Opdrachtinterface radioCommand public function execute (); class turnOnRadio implementeert radioCommand private $ radioControl; openbare functie __construct (radioControl $ radioControl) $ this-> radioControl = $ radioControl; public function execute () $ this-> radioControl-> turnOn (); class turnOffRadio implementeert radioCommand private $ radioControl; openbare functie __construct (radioControl $ radioControl) $ this-> radioControl = $ radioControl; public function execute () $ this-> radioControl-> turnOff (); // Client $ in = 'turnOffRadio'; // Invoker als (class_exists ($ in)) $ command = new $ in (new radioControl ()); else throw new Exception ('... Command Not Found ...'); $ command-> execute ();
Eerder hadden we maar één frequentie om op de radio te spelen, dus we hadden maar twee methoden, namelijk om de radio aan of uit te zetten. Maar stel je voor dat we na verloop van tijd meerdere frequenties te spelen hebben, waardoor we twee nieuwe methoden moeten toevoegen: TuneUp
en tuneDown
. Laten we eens kijken hoe we die kunnen toevoegen.
Wanneer we ontwerppatronen gebruiken, kunnen we hiermee wijzigingen aanbrengen of de functionaliteit uitbreiden zonder de clientcode te wijzigen. Dit is ook hier van toepassing. We gaan nog twee commando's toevoegen, maar onze client- en invokercode blijft zoals ze zijn.
Het toevoegen van nieuwe commando's vereist veranderingen op twee plaatsen. De eerste is om nieuwe commando's te maken die onze implementeren radioCommand
interface, en vervolgens is het definiëren van de daadwerkelijke implementatie van die commando's in de ontvanger.
class tuneUpRadio implementeert radioCommand private $ radioControl; openbare functie __construct (radioControl $ radioControl) $ this-> radioControl = $ radioControl; public function execute () $ this-> radioControl-> tuneUp (); class tuneDownRadio implementeert radioCommand private $ radioControl; openbare functie __construct (radioControl $ radioControl) $ this-> radioControl = $ radioControl; public function execute () $ this-> radioControl-> tuneDown ();
We zullen twee nieuwe methoden toevoegen in onze ontvangerklasse.
// Receiver class radioControl openbare functie inschakelenOn () // Radio-echo inschakelen "Radio inschakelen"; openbare functie turnOff () // Radio-echo uitschakelen "Radio uitschakelen"; openbare functie tuneUp () // Tuning Up Radio echo "Tuning Up Radio"; publieke functie tuneDown () // Radio-echo afstemmen "Radio afstemmen";
Dus we moeten het Command-ontwerppatroon gebruiken als we meerdere opdrachten uitvoeren en het maakt niet uit of die commando's met elkaar te maken hebben of niet. Ik heb mijn best gedaan om dit ontwerppatroon nader uit te werken en je kunt je feedback plaatsen in de sectie Opmerkingen.