Command Design Pattern + Action Delegate
Transcript of Command Design Pattern + Action Delegate
IEG 3080Tutorial 9
Prepared by Wilson
Outline Design Patterns
Creational Patterns Structural Patterns Behavioral Patterns
Project Phase 2
Design Patterns
Creational Structural BehavioralAbstract Factory
BuilderFactory Method
PrototypeSingleton
AdapterBridge
CompositeDecorator
FaçadeFlyweight
Proxy
Chain of Resp.CommandInterpreter
IteratorMediatorMementoObserver
StateStrategy
TemplateVisitor
Design Patterns Chain of Responsibility
Avoid coupling the sender of a request to its receiver. Chain the receivers and pass the request along the chain until the request is handled.
Example: Exception Handling
Receiver3
HandleRequest()
Receiver1
HandleRequest() Receiver2
HandleRequest()
Request
Design Patterns Chain of Responsibility
// The abstract "Handler“ class abstract class Handler { protected Handler successor;
public void SetSuccessor(Handler successor) { this.successor = successor; }
public abstract void HandleRequest(int request); }
// The "ConcreteHandler1“ class class ConcreteHandler1 : Handler { public override void HandleRequest(int request) { if (request >= 0 && request < 20) { Console.WriteLine("{0} handled request {1}", this.GetType().Name, request); } else if (successor != null) { successor.HandleRequest(request); } } }
// The "ConcreteHandler2“ class class ConcreteHandler2 : Handler { public override void HandleRequest(int request) { if (request >= 20 && request < 40) { Console.WriteLine("{0} handled request {1}", this.GetType().Name, request); } else if (successor != null) { successor.HandleRequest(request); } } }
Handler
HandleRequest ()
successor
ConcreteHandler1
HandleRequest ()
ConcreteHandler2
HandleRequest ()
Forward the request to next handler
Design Patterns Chain of Responsibility
static void Main() { // Setup Chain of Responsibility Handler h1 = new ConcreteHandler1(); Handler h2 = new ConcreteHandler2(); h1.SetSuccessor(h2);
// Generate and process request int[] requests = {5, 8, 4, 16, 24, 31, 27, 33};
foreach (int request in requests) { h1.HandleRequest (request); } }
Design Patterns Command
Encapsulate a request as an object. Allowing a request to be handled in the same way as an object item and to be parameterized.
Example: delegate in C#
Invoker CommandExecute()
ReceiverAction()
ConcreteCommandExecute()receiver
receiverAction()
Design Patterns Command
Command
Execute()
ConcreteCommandExecute() receiverAction()
// The abstract "Command“ class abstract class Command { protected Receiver receiver;
public Command(Receiver receiver) { this.receiver = receiver; }
public abstract void Execute(); }
// The "ConcreteCommand“ class class ConcreteCommand : Command { public ConcreteCommand(Receiver receiver) : base(receiver) { }
public override void Execute() { receiver.Action(); } }
Parameterize the command by compositing different concrete receiver
Action is performedfor the compositingreceiver
Design Patterns Command
Invoker
Receiver
Action()
// "Receiver" class Receiver { public void Action() { Console.WriteLine(“Actual action to perform"); } }
// "Invoker" class Invoker { private Command command;
public void SetCommand(Command command) { this.command = command; }
public void ExecuteCommand() { command.Execute(); } }
The method that will finally be called.
Accepting command and invoking command.
Design Patterns Command
aReceiver aClient aCommand anInvokernew Command(aReceiver)
StoreCommand(aCommand)
Execute()
Action()
Design Patterns Interpreter
Given a language, define a representation for its grammar along with interpreter that uses the representation to interpret sentences in the language.
AbstractExpressionInterpret(Context)
TerminalExpression NonterminalExpressionInterpret(Context) Interpret(Context)
Design Patterns Interpreter
// "AbstractExpression" abstract class AbstractExpression { public abstract void Interpret(Context context); }
// "TerminalExpression" class TerminalExpression : AbstractExpression { public override void Interpret(Context context) { Console.WriteLine("Called Terminal.Interpret()"); } }
// "NonterminalExpression" class NonterminalExpression : AbstractExpression { public override void Interpret(Context context) { Console.WriteLine("Called Nonterminal.Interpret()"); } }}
AbstractExpression
Interpret(Context)
TerminalExpression NonterminalExpression
Interpret(Context) Interpret(Context)
Should filled with interpretoperations with respect to the expression class
Design Patterns Iterator
Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation.
Example: the interface IEnumerator in C#
List ListIteratorFirst()Next()IsDone()CurrentItem()
index
Design Patterns Iterator
// “List”class List { private ArrayList items = new ArrayList();
public override ListIterator CreateIterator() { return new ListIterator(this); }
}
// “ListIterator" class ListIterator { private List aggregate; private int current = 0;
// Constructor public ListIterator(List aggregate) { this.aggregate = aggregate; }
public virtual object First() {….} public virtual object Next() {….} public virtual object CurrentItem() {….} public virtual bool IsDone() {….} }
The actual aggregate instance hides inside the iterator
The only exposedinterfaces
Colleague
Design Patterns Mediator
Define an object that encapsulates how a set of objects interact.
Mediator
Colleague
Colleague
Colleague
Design Patterns Mediator
Mediator
ConcreteMediator
Colleague
ConcreteColleague1
ConcreteColleague2
mediator
Design Patterns Mediator
// "Mediator" abstract class Mediator { public abstract void Send(string message, Colleague colleague); }
// "ConcreteMediator" class ConcreteMediator : Mediator { private ConcreteColleague1 colleague1; private ConcreteColleague2 colleague2;
public ConcreteColleague1 Colleague1 { set{ colleague1 = value; } }
public ConcreteColleague2 Colleague2 { set{ colleague2 = value; } }
Mediator
ConcreteMediator
public override void Send(string message, Colleague colleague) { if (colleague == colleague1) { colleague2.Notify(message); } else { colleague1.Notify(message); } } }
Centralize controlOn objects interaction
Reference is kept formessage forwarding
Design Patterns Mediator
// "Colleague" abstract class Colleague { protected Mediator mediator;
// Constructor public Colleague(Mediator mediator) { this.mediator = mediator; } }
// "ConcreteColleague1" class ConcreteColleague1 : Colleague { // Constructor public ConcreteColleague1(Mediator mediator) : base(mediator) { }
public void Send(string message) { mediator.Send(message, this); }
public void Notify(string message) { Console.WriteLine("Colleague1 gets message: " + message); } }
// "ConcreteColleague2" class ConcreteColleague2 : Colleague {…………..}
Colleague
ConcreteColleague1 ConcreteColleague2
Design Patterns References
Gamma, Erich et al, “Design Patterns: Elements of Reusable Object-Oriented Software,” Addison-Wesley.
Design Patterns with C# sample code: http://www.dofactory.com/Patterns/Patterns.aspx
Project Phase 2 You are required to implement:
Game controlling functions Movement Harpoon shooting
Collision detection functions Between main character and ball Between ball and harpoon
Project Phase 2 Game controlling functions
Movement:public class Form1 { ……… public Form1() { …… this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.MyKeyDown); } ………… public void MyKeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
{string k = e.KeyData.ToString();if (k.Equals(“Right”)) {
main_char.x += 5; } else if (k.Equals(“Left”)) {
main_char.x -=5;}
}}
Get the pressed key andchanges the position of the main character
Register an eventhandler to KeyDown event
Project Phase 2 Game controlling functions
Harpoon shooting:public class Form1 { // bullets object container BulletContainer bullets = new BulletContainer(); ………… public void MyKeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
{string k = e.KeyData.ToString();……
// press space to shoot bulletelse if (k.Equals(“Space”)) {
Bullet b = new Bullet(); bullets.add(b);
} }
……………..private void timer1_Tick(object sender, EventArgs e) { ………… foreach (Bullet b in bullets) { b.update(); } }
Create a harpoon after pressing shooting key
Update the existingharpoons in the gamescene
Project Phase 2 Game controlling functions
Harpoon shooting:public class Bullet { private int height; ………… public Bullet() { height = 0; } public void update() { height += 10; } …………… public void draw(Graphics g) { …..// draw a harpoon figure by the value of height }}
Project Phase 2 Collision detection functions
Between main character and ball Between ball and harpoon
Make uses of intersectsWith (.) method from Rectangle class. E.g. basic form of intersection detection is:
Rectangle aRectangle1 = new Rectangle();Rectangle aRectangle2 = new Rectangle();
// checking whether two rectangle area overlappedaRectangle1.intersectsWith(aRectangle2);