命令模式
一、紧耦合设计
package operation;
class Barbecuer{
public void BakeMutton() {
System.out.println("烤羊肉串!");
}
public void BakeChickenWing() {
System.out.println("烤鸡翅!");
}
}
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();
}
}
二、松耦合设计
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("烤羊肉串!");
}
public void BakeChickenWing() {
System.out.println("烤鸡翅!");
}
}
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();
}
}
有几个问题:
1.真实的情况并不是用户点一个菜,服务员就通知厨房去做一个,应该是点完烧烤后服务员一次性通知。
2.如果此时鸡翅没了,不应该是客户来判断有没有,应该是服务员或烤肉串者来否决这个请求。
3.客户到底点了哪些烧烤或饮料,这是需要记录日志的,以备收费,也包括后期的统计。
4.客户完全有可能因为点的羊肉串太多而考虑取消一些还没有制作的肉串。
三、松耦合后
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("烤羊肉串!");
}
public void BakeChickenWing() {
System.out.println("烤鸡翅!");
}
}
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("服务员:鸡翅没有了。");
}else {
orders.add(command);
SimpleDateFormat df=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("增加订单:"+command.getClass().getName()+"时间:"+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("取消订单:"+command.getClass().getName()+"时间:"+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.BakeMuttonCommand时间:2020-06-22 13:08:46
增加订单:operation.BakeMuttonCommand时间:2020-06-22 13:08:46
增加订单:operation.BakeChickenWingCommand时间:2020-06-22 13:08:46 烤羊肉串!
烤羊肉串! 烤鸡翅!
四、命令模式
命令模式:将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。
package operation;
class Receiver{
public void Action() {
System.out.println("执行请求!");
}
}
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();
}
}
五、命令模式作用
1.它能较容易地设计一个命令队列
2.在需要的情况下,可以较容易地将命令记入日志
3.允许接收请求的一方决定是否要否决请求
4.可以容易地实现对请求的撤销和重做
5.由于加进新的具体命令类不影响其他的类,因此增加新的具体命令类很容易。
最关键的优点就是命令模式把请求一个操作的对象与知道怎么执行的一个操作分割开。