Prezentace se nahrává, počkejte prosím

Prezentace se nahrává, počkejte prosím

Command. Definice Návrhový vzor Command je vzor chování (behaviorální návrhový vzor), ve kterém je objekt použit k zapouzdření všech informací potřebných.

Podobné prezentace


Prezentace na téma: "Command. Definice Návrhový vzor Command je vzor chování (behaviorální návrhový vzor), ve kterém je objekt použit k zapouzdření všech informací potřebných."— Transkript prezentace:

1 Command

2 Definice Návrhový vzor Command je vzor chování (behaviorální návrhový vzor), ve kterém je objekt použit k zapouzdření všech informací potřebných ke zpožděnému spuštění události. Tyto informace zahrnují jméno metody, objekt, kterému metoda patří a hodnoty jejích parametrů.

3 Motivace Návrhový vzor Command je vzor chování (behaviorální návrhový vzor), ve kterém je objekt použit k zapouzdření všech informací potřebných ke zpožděnému spuštění události. Tyto informace zahrnují jméno metody, objekt, kterému metoda patří a hodnoty jejích parametrů.  Potřebujeme reprezentovat žádost o vykonání akce  Standardní přístup je zavolat metodu na objektu  Taková metoda se ale provede okamžitě  My potřebujeme speciální sémantiku  Zpožděné vykonání  Vzdálené vykonání  Explicitní kontrola akcí  Zřejmě potřebujeme nějakou abstrakci volání

4 „Kuchařka“ Návrhový vzor Command je vzor chování (behaviorální návrhový vzor), ve kterém je objekt použit k zapouzdření všech informací potřebných ke zpožděnému spuštění události. Tyto informace zahrnují jméno metody, objekt, kterému metoda patří a hodnoty jejích parametrů.  Definujeme si Command interface se signaturou metody „execute()“  Vytvoříme konkrétní implementace Command interface, které zapouzdřují: „receiver“ objekt („na čem se má akce zavolat“) cílová metoda („co se má zavolat“) argumenty pro cílovou metodu  vytvoříme instanci Command objektu pro každou událost  předáme Command objekt invokeru (senderu)  invoker rozhodne, kdy bude execute() zavolána

5 Obecná struktura

6 Obecná struktura s příkladem document->Paste() Paste commandMenu item Document Aplikace při vytváření GUI

7 Konkrétních Commandů může (a typicky je) několik

8 Příklad class Light { public void TurnOn() { Console.WriteLine("Light is on"); } public void TurnOff() { Console.WriteLine("Light is off"); } class Switch { private ICommand upCommand, downCommand; public Switch(ICommand up, ICommand down) { upCommand = up; downCommand = down; } public void FlipUp() { upCommand.Execute(); } public void FlipDown() { downCommand.Execute(); } ReceiverInvoker class LightOnCommand : ICommand { private Light myLight; public LightOnCommand(Light light) { myLight = light; } public void Execute() { myLight.TurnOn(); } class LightOffCommand : ICommand { private Light myLight; public LightOffCommand(Light light) { myLight = light; } public void Execute() { myLight.TurnOff(); } Command objekty

9 Příklad static void Main(string[] args) { Light light = new Light(); ICommand lightOn = new LightOnCommand(light); ICommand lightOff = new LightOffCommand(light); Switch mySwitch = new Switch(lightOn, lightOff); mySwitch.FlipUp(); mySwitch.FlipDown(); } Client

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

11 MacroCommand  Kompozice  Posloupnosti volání (makro)  Composite pattern  Composite objekt nemá receiver public class MacroCommand : ICommand { private List commands; public void Execute() { foreach (ICommand c in commands) c.Execute(); //... }

12 Undo, redo  Je třeba ukládat stav receiveru  Reference na samotný 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

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

14 Známá použití  Undo  GUI toolkity  Java Swing – interface Action, metoda actionPerformed (~Execute)  WPF.NET – ICommand (Execute, CanExecute)  ThreadPool  odkládání požadavků do fronty - zpracování, až na ně přijde řada  Předávání požadavků po síti, callbacky  Sekvence příkazů a “transakční” chování

15 Intermezzo: Visual Novels  Interaktivní počítačová hra užívající vesměs statickou grafiku  Pouze jednoduché posuvné animace  Interaktivita přes občasně prezentovanou volbu akce (story branching)  Typicky množství endingů  Kliknutí posouvá hráče kupředu  Ukáže nový text  Spustí události na jevišti JevištěTextové poleHerci

16 Fungus  Flowchart  Množina blocků (orientovaný graf)  Popisuje vztahy mezi blocky  Má vstupní bod a podmínky pro spuštění  Block  Množina commandů (pole)  Má na starosti jejich vykonávání

17 Fungus – Command class public class Command : MonoBehaviour { [HideInInspector] public string errorMessage = ""; [HideInInspector] public int indentLevel; [NonSerialized] public int commandIndex; [NonSerialized] public bool isExecuting; [NonSerialized] public float executingIconTimer; [NonSerialized] public Block parentBlock; public virtual void Execute() { OnEnter(); } public virtual void Continue(int nextCommandIndex) { OnExit(); if (parentBlock != null) { parentBlock.jumpToCommandIndex = nextCommandIndex; } public virtual void StopParentBlock() { OnExit(); if (parentBlock != null) parentBlock.Stop(); } public virtual void OnStopExecuting() { } public virtual void OnEnter() { } public virtual void OnExit() { } public virtual void OnReset() { } /* Více kódu... */ } Metoda Execute()

18 Fungus – Block class (ExecuteBlock method) protected virtual IEnumerator ExecuteBlock(Action onComplete = null) { Flowchart flowchart = GetFlowchart(); executionState = ExecutionState.Executing; int i = 0; while (true) { if (jumpToCommandIndex > -1) { i = jumpToCommandIndex; jumpToCommandIndex = -1; } /* Sanity checky, přeskočení zakázaných commandů, breaknutí z while na konci listu, etc... */ Command command = commandList[i]; activeCommand = command; /* Další sanity checky... */ command.isExecuting = true; command.Execute(); // Wait until the executing command sets another command to jump to via Command.Continue() while (jumpToCommandIndex == -1) { yield return null; } command.isExecuting = false; } executionState = ExecutionState.Idle; activeCommand = null; if (onComplete != null) onComplete(); }

19 Fungus – Jump Command [CommandInfo("Flow", "Jump", "Move execution to a specific Label command")] public class Jump : Command { [Tooltip("Label to jump to")] public Label targetLabel; public override void OnEnter() { if (targetLabel == null) { Continue(); return; } foreach (Command command in parentBlock.commandList) { Label label = command as Label; if (label != null && label == targetLabel) { Continue(label.commandIndex + 1); break; } /* Metody pro Unity inspektor... */ }

20 Fungus – Say Command [CommandInfo("Narrative", "Say", "Writes text in a dialog box.")] public class Say : Command, ILocalizable { public override void OnEnter() { /* Sanity checky... */ SayDialog sayDialog = SayDialog.GetSayDialog(); /* Další sanity checky... */ Flowchart flowchart = GetFlowchart(); sayDialog.gameObject.SetActive(true); sayDialog.SetCharacter(character, flowchart); sayDialog.SetCharacterImage(portrait); string displayText = storyText; /* Parsování vlastních tagů... */ string subbedText = flowchart.SubstituteVariables(displayText); sayDialog.Say(subbedText, !extendPrevious, waitForClick, fadeWhenDone, voiceOverClip, delegate { Continue(); }); } public override void OnStopExecuting() { SayDialog sayDialog = SayDialog.GetSayDialog(); if (sayDialog == null) return; sayDialog.Stop(); } /* Metody pro Unity inspektor, lokalizační metody, pomocné metody... */ }

21 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í

22 Otázky, diskuze Návrhový vzor Command je vzor chování (behaviorální návrhový vzor), ve kterém je objekt použit k zapouzdření všech informací potřebných ke zpožděnému spuštění události. Tyto informace zahrnují jméno metody, objekt, kterému metoda patří a hodnoty jejích parametrů. Otázky, diskuze


Stáhnout ppt "Command. Definice Návrhový vzor Command je vzor chování (behaviorální návrhový vzor), ve kterém je objekt použit k zapouzdření všech informací potřebných."

Podobné prezentace


Reklamy Google