Design pattern learning notes (39) -- command pattern and its implementation

Keywords: Java

Command mode
1, Tight coupling design

package operation;
class Barbecuer{

	public void BakeMutton() {
		System.out.println("shish kebab!");
	}

	public void BakeChickenWing() {
		System.out.println("Roast chicken wings!");
	}
}
public  class Main{
	public static void main(String[] args){
		Barbecuer boy=new Barbecuer();
		boy.BakeMutton();
		boy.BakeMutton();
		boy.BakeMutton();
		boy.BakeChickenWing();
		boy.BakeMutton();
		boy.BakeMutton();
		boy.BakeChickenWing();
	}
}

2, Loose coupling design

package operation;
abstract class Command{
	protected Barbecuer receiver;
	public Command(Barbecuer receiver) {
		this.receiver=receiver;
	}
	public abstract void ExcuteCommand();
}
class Barbecuer{
	
	public void BakeMutton() {
		System.out.println("shish kebab!");
	}
	public void BakeChickenWing() {
		System.out.println("Roast chicken wings!");
	}
}
class BakeMuttonCommand extends Command{
	 
	public BakeMuttonCommand(Barbecuer receiver) {
		super(receiver);
		
	}
 
	
	public void ExcuteCommand() {
		
		receiver.BakeMutton();
	}
	
}
class BakeChickenWingCommand extends Command{
 
	public BakeChickenWingCommand(Barbecuer receiver) {
		super(receiver);
		
	}
 

	public void ExcuteCommand() {
	
		receiver.BakeChickenWing();
	}
}



class Waiter{
	private Command command;

	public void SetOrder(Command command) {
		this.command=command;
	}

	public void Notify() {
		command.ExcuteCommand();
	}
}
public  class Main{
	public static void main(String[] args){
	
		Barbecuer boy=new Barbecuer();
		Command bakeMuttonCommand1=new BakeMuttonCommand(boy);
		Command bakeMuttonCommand2=new BakeMuttonCommand(boy);
		Command bakeChikenWingCommand1=new BakeChickenWingCommand(boy);
		Waiter girl=new Waiter();
	
		girl.SetOrder(bakeMuttonCommand1);
		girl.Notify();
		girl.SetOrder(bakeMuttonCommand2);
		girl.Notify();
		girl.SetOrder(bakeChikenWingCommand1);
		girl.Notify();
	}
}

There are several questions:
1. The real situation is not that the user orders a dish, the waiter will inform the kitchen to make one. It should be a one-time notice after ordering the barbecue.
2. If the chicken wings are gone at this time, it should not be the customer's judgment. It should be the waiter or the barbecue maker to reject the request.
3. What kind of barbecue or drinks the customer ordered should be recorded in the log for charging, including later statistics.
4. Customers are likely to consider canceling some meat kebabs that have not been made due to too many mutton kebabs.
3, After loose coupling

package operation;


import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
 
class Barbecuer{
	
	public void BakeMutton() {
		System.out.println("shish kebab!");
	}
	
	public void BakeChickenWing() {
		System.out.println("Roast chicken wings!");
	}
}
abstract class Command{
	protected Barbecuer receiver;
	public Command(Barbecuer receiver) {
		this.receiver=receiver;
	}
	public abstract void ExcuteCommand();
}

class BakeMuttonCommand extends Command{
 
	public BakeMuttonCommand(Barbecuer receiver) {
		super(receiver);
		
	}
	public void ExcuteCommand() {
		
		receiver.BakeMutton();
	}
	
}
class BakeChickenWingCommand extends Command{
 
	public BakeChickenWingCommand(Barbecuer receiver) {
		super(receiver);
		
	}
 
	public void ExcuteCommand() {
	
		receiver.BakeChickenWing();
	}
}

class Waiter{
	private ArrayList<Command>orders=new ArrayList<Command>();
	public void SetOrder(Command command) {
		if(command.getClass().getName()=="fx.BakeChickenWingCommand") {
			System.out.println("Waiter: the wings are gone.");
		}else {
			orders.add(command);
			SimpleDateFormat df=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			System.out.println("Add order:"+command.getClass().getName()+"Time:"+df.format(new Date()));
		}
	}

	public void CancelOrder(Command command) {
		orders.remove(command);
		SimpleDateFormat df=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("cancellation of order:"+command.getClass().getName()+"Time:"+df.format(new Date()));
	}
	public void Notify() {
		Iterator<Command>cmd=orders.iterator();
		while(cmd.hasNext()) {
			cmd.next().ExcuteCommand();
		}
	}
}
 
public  class Main{
	public static void main(String[] args){
		
		Barbecuer boy=new Barbecuer();
		Command bakeMuttonCommand1=new BakeMuttonCommand(boy);
		Command bakeMuttonCommand2=new BakeMuttonCommand(boy);
		Command bakeChikenWingCommand1=new BakeChickenWingCommand(boy);
		Waiter girl=new Waiter();
		
		girl.SetOrder(bakeMuttonCommand1);
		girl.SetOrder(bakeMuttonCommand2);
		girl.SetOrder(bakeChikenWingCommand1);
		girl.CancelOrder(bakeMuttonCommand1);
		girl.Notify();
	}
}

Operation result:

Add order: operation.BakeMuttonCommand Time: June 22, 2020 13:08:46
Add order: operation.BakeMuttonCommand Time: June 22, 2020 13:08:46
Add order: operation.BakeChickenWingCommand Time: 2020-06-22 13:08:46 grilled mutton kebab!
shish kebab! Roast chicken wings!

4, Command mode
Command mode: encapsulate a request as an object so that you can parameterize customers with different requests; queue or log requests; and support undoable operations.

package operation;

class Receiver{
	public void Action() {
		System.out.println("Execute request!");
	}
}
abstract class Command{
	protected Receiver receiver;
	public Command(Receiver receiver) {
		this.receiver=receiver;
	}
	abstract public void Excute();
}
class ConcreteCommand extends Command{
	public ConcreteCommand(Receiver receiver) {
		super(receiver);
	}
 
	
	public void Excute() {
	
		receiver.Action();
	}
}
class Invoker{
	private Command command;
 
	public void setCommand(Command command) {
		this.command = command;
	}
	public void ExecuteCommand() {
		command.Excute();
	}
}
public  class Main{
	public static void main(String[] args){
		Receiver r=new Receiver();
		Command c=new ConcreteCommand(r);
		Invoker i=new Invoker();
		i.setCommand(c);
		i.ExecuteCommand();
	}
}

5, Command mode function
1. It can easily design a command queue
2. It is easy to log commands when necessary
3. Allow the receiving party to decide whether to reject the request
4. It is easy to revoke and redo the request
5. Since adding a new specific command class does not affect other classes, it is easy to add a new specific command class.
The key advantage is that the command mode separates the object requesting an operation from an operation that knows how to perform.

Posted by scottd on Sun, 21 Jun 2020 22:57:09 -0700