游戏中的设计模式九:命令模式

发表于2018-03-26
评论0 2.2k浏览
本篇文章给大家介绍下设计模式中的命令模式。命令模式是为了解决命令的请求者和命令的实现者之间的耦合关系。请求一命令的形式包裹在对象中,并传给调用对象。调用对象寻找可以处理该命令的合适对象,并把该命令传给相应的对象,该对象执行命令。

本文介绍在Unity3d客户端执行按钮点击操作,发起相应的命令并执行命令,将操作行为的请求者与实现者解耦。常常运用于在对行为进行“记录”、“撤销/恢复”、“事务”等处理。

模式角色

调用者(Invoker)、命令(Command) 、接收者(Received)

开发案例

调用者类:
using System.Collections;  
using System.Collections.Generic;  
using UnityEngine;  
public class Invoker  
{  
    ICommand jumpCommand = new JumpCommand(new JumpReceived());  
    ICommand pickCommand = new PickCommand(new PickReceived());  
    public ICommand ExcuteCommand()  
    {  
        if (Input.GetKeyDown(KeyCode.J))  
        {  
            return jumpCommand;  
        }  
        else if (Input.GetKeyDown(KeyCode.P))  
        {  
            return pickCommand;  
        }  
        return null;  
    }  
}  

命令类:
using System.Collections;  
using System.Collections.Generic;  
using UnityEngine;  
public abstract class ICommand   
{  
    public IReceived received;  
    public abstract void Excute();  
}  

具体命令类---跳跃类:
using System;  
using System.Collections;  
using System.Collections.Generic;  
using UnityEngine;  
public class JumpCommand : ICommand  
{  
    public JumpCommand(IReceived received)  
    {  
        this.received = received;  
    }  
    public override void Excute()  
    {  
        Debug.Log("发出跳跃命令");  
        received.Action();  
    }  
}  

具体命令类---拾取类:
using System;  
using System.Collections;  
using System.Collections.Generic;  
using UnityEngine;  
public class PickCommand : ICommand  
{  
    public PickCommand(IReceived received)  
    {  
        this.received = received;  
    }  
    public override void Excute()  
    {  
        Debug.Log("发出拾取命令");  
        received.Action();  
    }  
}  

接受者类:
using System.Collections;  
using System.Collections.Generic;  
using UnityEngine;  
public abstract class IReceived  
{  
    public abstract void Action();  
}  

具体接受者类---跳跃类:
using System;  
using System.Collections;  
using System.Collections.Generic;  
using UnityEngine;  
public class JumpReceived : IReceived  
{  
    public override void Action()  
    {  
        Debug.Log("接收跳跃请求");  
    }  
}  

具体接受者类---拾取类:
using System;  
using System.Collections;  
using System.Collections.Generic;  
using UnityEngine;  
public class PickReceived : IReceived  
{  
    public override void Action()  
    {  
        Debug.Log("接收拾取请求");  
    }  
}  

测试类:
using System.Collections;  
using System.Collections.Generic;  
using UnityEngine;  
public class CommandPattern : MonoBehaviour  
{  
    private GameObject slider { get; set; }  
    private Invoker invoker { get; set; }  
    private void Start()  
    {  
        slider = GameObject.Find("Slider");  
        invoker = new Invoker();  
    }  
    private void Update()  
    {  
        if (slider != null)  
        {  
            ICommand command = invoker.ExcuteCommand();  
            if (command != null)  
            {  
                command.Excute();  
            }  
        }  
    }  
}  

测试完成,这样命令模式将键盘操作请求与接收通过命令Command进行隔离;
这样我们通过对命令模式进行扩展,可以对各个行为进行记录、事务/撤销(Undo、Redo)、恢复操作;
即将各个命令进行添加到容器内,用于存放各个命令。

模式分析

优点:降低系统耦合性、新的命令很容易融入到系统内
确定:导致系统中有过多的具体命令类与接收者类


如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引