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

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

搭建场景

简单的搭建一个场景就行 ,随便准备一个物体放在场景中位置Reset一下即可。

代码编写
  1. 定义接口(或者抽象类)ICommand 用来规范Command的行为。注意在命令模式中命令是桥接作用负责接受者和执行者之间的联调。所以一般会有很多的命令,每个命令都会有ICommand规范的方法同时也可以添加其他的方法。
csharp 复制代码
public interface ICommand{
	void Execute();
	void UnExecute();
}
  1. 实现定义的接口(或者抽象类) 同时为了具有这种桥接的作用,MyCommand 需要持有Receiver
csharp 复制代码
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.接受者,接受者的意思是接受命令执行自身的函数

csharp 复制代码
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.执行者,挂载在场景中的任意物体上(建议放空物体上)负责代码的执行 调度

csharp 复制代码
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); }
}

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

相关推荐
sponge'11 分钟前
opencv学习笔记2:卷积、均值滤波、中值滤波
笔记·python·opencv·学习
on the way 12317 分钟前
行为型设计模式之Mediator(中介者)
java·设计模式·中介者模式
竹言笙熙1 小时前
Polarctf2025夏季赛 web java ez_check
java·学习·web安全
过河不拆乔1 小时前
AWS 公开数据集下载与操作说明
学习·云计算·aws
小狗爱吃黄桃罐头1 小时前
正点原子[第三期]Arm(iMX6U)Linux移植学习笔记-12.1 Linux内核启动流程简介
linux·arm开发·学习
周某某~2 小时前
二.单例模式‌
java·单例模式·设计模式
十五年专注C++开发3 小时前
设计模式之单例模式(二): 心得体会
开发语言·c++·单例模式·设计模式
hstar95273 小时前
三十五、面向对象底层逻辑-Spring MVC中AbstractXlsxStreamingView的设计
java·后端·spring·设计模式·架构·mvc
心之所向,自强不息3 小时前
【Unity Shader编程】之让画面动起来
unity·游戏引擎
pengyu3 小时前
【Java设计原则与模式之系统化精讲:壹】 | 编程世界的道与术(实战指导篇)
java·后端·设计模式