设计模式学习-简单的命令模式例子

上一章节介绍过了命令模式,这一篇文章就简单的做一个小案例来巩固学习

搭建场景

简单的搭建一个场景就行 ,随便准备一个物体放在场景中位置Reset一下即可。
在这里插入图片描述

代码编写
  1. 定义接口(或者抽象类)ICommand 用来规范Command的行为。注意在命令模式中命令是桥接作用负责接受者和执行者之间的联调。所以一般会有很多的命令,每个命令都会有ICommand规范的方法同时也可以添加其他的方法。
public interface ICommand{
	void Execute();
	void UnExecute();
}
  1. 实现定义的接口(或者抽象类) 同时为了具有这种桥接的作用,MyCommand 需要持有Receiver
public enum Direction{
	Left,
	Down,
	Right,
	Up
}
public class MyCommand : ICommand{
	private Receiver _receiver;
	private Direction _direction;
	private GameObject _moveObj;
	private float _distance;
	
	public MyCommand(Direction direction,Receiver receiver,GameObject moveObj,float distance){
		this._receiver = receiver;
		this._direction = direction;
		this._moveObj = moveObj;
		this._distance = distance;
	}
	public void Execute(){
		_receiver.OperationDirection(_moveObj,_direction,_distance );
	}
	public void UnExecute(){
		_receiver.OperationDirection(_moveObj,InverseDirection(_direction),_distance );
	}
	private Direction InverseDirection(Direction direction){
		switch(direction){
		case Direction.Left:
			return Direction.Right;
		case Direction.Right:
			return Direction.Left;
		case Direction.Up:
			return Direction.Down;
		case Direction.Down:
			return Direction.Up;
		}
	}

	public override void ToString(){
		return $"{_moveObj.name}:{DirectionStr(_direction)}:{_distance.ToString()}";
	}
	private string DirectionStr(Direction dircteion) {
    switch (dircteion) 
    { 
        case Direction.Left:
            return "Left";
        case Direction.Right:
            return "Right";
        case Direction.Up:
            return "Up";
        case Direction.Down:
            return "Down";
        default:
            return default;
    }
}
}

3.接受者,接受者的意思是接受命令执行自身的函数

public class Receiver{
	public void OperationDirection(GameObject moveObj,Direction direction,float distance){
		switch(direction){
		case Direction.Left:
			MoveX(moveObj,-distance);
			break;
		case Direction.Right:
			MoveX(moveObj,distance);
			break;
		case Direction.Up:
			MoveY(moveObj,distance);
			break;
		case Direction.Up:
			MoveY(moveObj,-distance);
			break;
		}
	}
	
	private void MoveX(GameObject moveObj,float distance){
		var tempPos = moveObj.transform.position;
		tempPos .x+=distance;
		moveObj.transform.position = tempPos;
	}
	private void MoveY(GameObject moveObj,float distance){
		var tempPos = moveObj.transform.position;
		tempPos.y+=distance;
		moveObj.transform.position = tempPos;
	}
}

4.执行者,挂载在场景中的任意物体上(建议放空物体上)负责代码的执行 调度

public class InputHandler : MonoBehaviour{
	private Receiver _receiver;
	[SerializeField]
    [Tooltip("移动距离")]
	private float distance = 1f;
	private List<ICommand> commands = new List<ICommand>(); // 存储命令方便回溯
 	private int currentCommandNum = 0;  // 当前执行的命令
 	public GameObject moveObj;  //控制的物体上面的那个Move直接拖到这里进行绑定 
	
	private void Start()
	{
    	_receiver= new Receiver();
		// 空处理 可写可不写
	}
	private void Move(Direction direction){
		var command = new MyCommand(direction,_receiver,moveObj,distance);
		command.Execute();
		commands.Add(command);
		currentCommandNum++;
	}
	private void Undo(){
		if(currentCommandNum > 0 ){
			currentCommandNum--;
			MyCommand command= (MyCommand )commands[currentCommandNum];
			command.UnExecute();
		}
	}
	private void Redo(){
		if (currentCommandNum < commands.Count) { 
	    MyCommand command= (MyCommand )commands[currentCommandNum];
	    currentCommandNum++;
	    command.Execute();
		}
	}
	void OnGUI()
	{
	    string label = "   start";
	    if (currentCommandNum == 0)
	    {
	        label = ">" + label;
	    }
	    label += "\n";
	
	    for (int i = 0; i < commands.Count; i++)
	    {
	        if (i == currentCommandNum - 1)
	            label += "> " + commands[i].ToString() + "\n";
	        else
	            label += "   " + commands[i].ToString() + "\n";
	    }
	    GUI.Label(new Rect(0, 0, 400, 800), label);
	}
	 private void Update()
		 {
		     if (Input.GetKeyDown(KeyCode.UpArrow)|| Input.GetKeyDown(KeyCode.W)) 
		     { moveUp(); }
		     if (Input.GetKeyDown(KeyCode.DownArrow) || Input.GetKeyDown(KeyCode.S)) 
		     { moveDown(); }
		     if (Input.GetKeyDown(KeyCode.LeftArrow) || Input.GetKeyDown(KeyCode.A))
		      { moveLeft(); }
		     if (Input.GetKeyDown(KeyCode.RightArrow) || Input.GetKeyDown(KeyCode.D)) 
		     { moveRight(); }
		     if (Input.GetKeyDown(KeyCode.R))
		     { Redo(); }
		     if (Input.GetKeyDown(KeyCode.U))
		     { Undo(); }
		 }
	 void moveUp() { Move(Direction.Up); }
	 void moveDown() { Move(Direction.Down); }
	 void moveLeft() {  Move(Direction.Left); }
	 void moveRight() { Move(Direction.Right); }
}

现在就基本上已经做完了,是一个很简单的案例用来巩固学习命令模式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值