00:00

Understanding the Command Design Pattern in Object-Oriented Programming

The Command design pattern encapsulates commands into objects, enabling delayed, remote, or undoable executions. By separating the requester and executor, it promotes flexibility and extensibility in handling actions. The pattern involves interfaces, concrete commands, invokers, receivers, and clients, allowing diverse implementations and behaviors. An example demonstrates how commands are created, associated with receivers, and executed through invokers, showcasing the pattern's utility and structure.

Télécharger la présentation

Understanding the Command Design Pattern in Object-Oriented Programming

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Command Jan Jevčák

  2. Motivace Návrhový vzor Command je vzor chování, který zapouzdřuje příkazy do objektů se všemi informacemi potřebnými pro vykonání daného příkazu. Zapouzdření umožňuje předat příkaz jako parametr, vytvořit frontu příkazů nebo jejich historii. ■ Potřebujeme reprezentovat žádost o vykonání akce ❑ standardní přístup je zavolat metodu na objektu ❑ metoda se provede okamžitě ❑ potřebujeme speciální sémantiku ❑ zpožděné vykonání ❑ vzdálené vykonání ❑ explicitní kontrola akcí ❑ potřeba abstrakce volání ❑ oddělení volajícího (požadavku) a vykonávajího objektu

  3. Motivace / Naivní implementace public void CheckAction(string action) { if (action == "New") { // handle action for new command } else if (action == "Open") { // handle action for open command } else if (action == "Save") { // handle action for save command } else (action == "Quit") { // handle action for quit command } } Porušení principu otevřenosti a uzavřenosti OOP

  4. Obecná struktura

  5. Účastníci Command  Interface se signaturou metody execute() ConcreteCommand  Konkrétní implementace  Drží recievera a parametry, se kterými má být vykonán  Implementuje execute() zavoláním příslušných operací na Reciever Client  Vytváří Command objekty a nastavuje Reciver Invoker  Zajistí provedení daného commandu  Možnost několika zcela odlišných Invokerů Reciever  Třída, která ví, jak příkaz provést, nebo na které je příkaz prováděn

  6. Konkrétní použití, runtime

  7. Struktura příkladu Menu item Aplikace při vytváření GUI Document Save command document->Save()

  8. Příklad Interface class PDFDocument { public void Save() { Console.WriteLine("PDF Document has been saved."); } } Receiver public interface ICommand { void Execute(); } Command třída Invoker class SaveCommand : ICommand { private PDFDocument _pdfDocument; class MenuItem { private ICommand _command; public SaveCommand(PDFDocument pdfDocument) { _pdfDocument = pdfDocument; } public MenuItem(ICommand command) { _command = command; } public void Execute() { _pdfDocument.Save(); } public void Click() { if (_command != null) { _command.Execute(); } } } }

  9. Příklad Client internal class Program { static void Main(string[] args) { // Creating receiver PDFDocument pdfDocument = new PDFDocument(); // Creating command and associating with receiver ICommand saveCommand = new SaveCommand(pdfDocument); // Creating invoker MenuItem menuItem = new MenuItem(saveCommand); // Simulating user click menuItem.Click(); } }

  10. Příklad

  11. Příklad public interface ICommand { void Execute(); } class Light { void TurnOn() { WriteLine("Light on"); } Receiver Interface class LightOnCommand : ICommand { private Light myLight; void TurnOff() { WriteLine("Light off"); } LightOnCommand(Light light) { myLight = light; } } Invoker class Switch { private ICommand upCommand, downCommand; void Execute() { myLight.TurnOn(); } } public Switch(ICommand up, ICommand down) { upCommand = up; downCommand = down; } class LightOffCommand : ICommand { private Light myLight; LightOffCommand(Light light) { myLight = light; } public void FlipUp() { upCommand.Execute(); } public void Execute() { myLight.TurnOff(); } public void FlipDown() { downCommand.Execute(); } Command třídy } }

  12. Příklad - rozšíření public interface ICommand { void Execute(); } class Fan { void StartRotate() { WriteLine("Fan rotating"); } Jiný receiver class FanOnCommand : ICommand { private Fan myFan; void StopRotate() { WriteLine("Fan not rotating"); } FanOnCommand(Fan fan) { myFan = fan; } } class Switch { private ICommand upCommand, downCommand; void Execute() { myFan.StartRotate(); } } public Switch(ICommand up, ICommand down) { upCommand = up; downCommand = down; } class FanOffCommand : ICommand { private Fan myFan; FanOffCommand(Fan fan) { myFan = fan; } public void FlipUp() { upCommand.Execute(); } void Execute() { myFan.StopRotate(); } public void FlipDown() { downCommand.Execute(); } } Jiné command objekty }

  13. MacroCommand ■ Kompozice ❑ posloupnosti volání (makro) ❑ založeno na Composite pattern ❑ chování makra stejné jako jedné akce class MacroCommand : ICommand { private List<ICommand> commands; void Execute() { foreach (ICommand c in commands) c.Execute(); // ... } }

  14. Undo, redo ■ Je třeba ukládat stav receiveru ❑ reference na objekt receiveru ❑ argumenty volání Command objektu ❑ původní hodnoty receiveru ■ Command objekty občas musí být kopírovány ❑ pokud se dále může měnit jejich stav ❑ prototype pattern ■ Pozor na chyby při undo/redo ❑ zajistit konzistentní stav uložených command objektů (Memento) ■ Alternativa: kompenzující opreace ❑ např. vypni - zapni

  15. Příklad - Undo interface ICommand { void Execute(); void Undo(); } Nová metoda class PasteCommand : ICommand { private Document document; private string oldText; PasteCommand(Document doc) { document = doc; } void Execute() { oldText = document.GetText(); document.Paste(); } Uloží stav void Undo() { document.SetText(oldText); } Obnoví stav z uložených hodnot }

  16. Známé použití Multi-level Undo • execute/undo, uchování/vytvoření předchozího stavu Macro recording GUI toolkity • Java Swing – interface Action, metoda actionPerformed • WPF .NET – ICommand ThreadPool • odkládání požadavků do fronty - zpracování, až na ně přijde řada Parallel / cluster / distributed computing • hi-perf scheduler, job queues Předávání požadavků po síti, callbacky Progress bar • getEstimatedDuration() Wizards • naklikat commandy, pak je najednou provést “transakční” chování • rollback, roll-forward • • • • • • • • •

  17. Související vzory ■ Composite ❑ vytváření maker (MacroCommand) ■ Memento ❑ uchovávání stavu objektů pro undo ■ Prototype ❑ při undo ukládání kopií akcí ■ Chain of Responsibility ❑ grafické toolkity – Command objekt může zpracovávat víc příjemců ❑ propagace změny stavu, řetězení

  18. Shrnutí ■ Výhody ❑ oddělení volajícího(požadavku) a vykonávajícího objektu ❑ rozšiřitelnost - jednoduché přidání nových Commands ■ Nevýhody ❑ rychle rostoucí počet tříd - každý Command je nová třída ■ Použitelnost ❑ parametrizace objektů pomocí akcí k provedení ❑ podpora undo operace ❑ podpora logování změn jednotlivých operací ❑ řazení požadavků ve frontě a jejich provádění v různých časech

More Related