当前位置:网站首页>Command mode - unity
Command mode - unity
2022-07-07 19:13:00 【Just be interesting】
List of articles
Command mode
Command mode is an object behavior mode , adopt The request between the requester and the performer is extracted and encapsulated into an object , Thus, the responsibility of sending the request is separated from the responsibility of executing the request . The requester and the executor communicate through the command object , This allows the command object to be stored , management , Deliver, etc .
Command mode is a very common mode in behavioral mode , It is also very important in game development . By managing and storing a large number of commands , It ensures the order and unity of commands . When using software , We often use undo , How the software performs undo , It is obviously to save every step of your operation , Restore by reading each step . This is the command mode , Each step is a command .
for example , Remote control and TV , The remote control is the requestor , Television is the executor , Who is the order , The buttons on the remote control are commands . Restaurants usually have a menu for customers to choose from , The waiter passes the menu to the chef , The chef is responsible for cooking . The dish selected in the menu is a command , The waiter acts as a middleman ( Belongs to the caller ), He is not responsible for carrying out , Responsible for delivering and managing these menus ( command ), And the menu will eventually be taken by the chef , And start the mission ( The chef is the executor ). How vivid , This is the wisdom of life .
structure
explain
- Abstract command (Command) - Generally, there is only one interface to execute command methods ( There can also be a cancellation method , Of course, if necessary )
- Specific commands (Concrete Command)- Concrete implementation classes of abstract commands , Does not implement the method itself , As the carrier of implementer parameters , Delegate work to implementers .
- Implementer (Receiver)- A class that implements business logic , Is the class that finally completes the method , Almost all objects can act as implementers .
- caller (Invoker)- There are multiple command objects stored , No direct access to implementers , Executing requests through command objects .( The command object itself is not created , Nor does it execute business methods ), It mainly manages command objects , Store , Execution, etc .
Realization
This example may be tedious , But in general, it is not too complicated .
Mainly to achieve recovery and revoke And so on .
Drive by command UI Move
Move enum
public enum MoveDirection
{
Left,
Right,
Up,
Down,
}
UI Move - Implementer ( The singleton pattern , Just one copy )
public class UIMove
{
private static UIMove _instacne = new UIMove();
// Moving distance
private const float MoveDistance = 100f;
public static UIMove Instacne => _instacne;
private UIMove() {
}
// Move
public void Move(RectTransform rt, MoveDirection direction)
{
Vector3 position = rt.position;
rt.position = direction switch
{
MoveDirection.Left => new Vector3(position.x - MoveDistance, position.y, position.z),
MoveDirection.Right => new Vector3(position.x + MoveDistance, position.y, position.z),
MoveDirection.Up => new Vector3(position.x, position.y + MoveDistance, position.z),
MoveDirection.Down => new Vector3(position.x, position.y - MoveDistance, position.z),
_ => throw new ArgumentOutOfRangeException(nameof(direction)),
};
}
}
The command interface - Abstract command
public interface ICommand
{
// perform
void Execute();
// revoke
void Undo();
// Command to convert string
string ToString();
}
Mobile command - Specific commands
public class MoveCommand : ICommand
{
// Keep the only one
private readonly UIMove _receiver;
private readonly RectTransform _transform;
private readonly MoveDirection _direction;
public MoveCommand(MoveDirection direction, RectTransform transform)
{
_direction = direction;
_transform = transform;
_receiver = UIMove.Instacne; // A single example
}
public void Execute() => _receiver.Move(_transform, _direction);
public void Undo()
{
switch (_direction)
{
case MoveDirection.Left:
_receiver.Move(_transform, MoveDirection.Right);
break;
case MoveDirection.Right:
_receiver.Move(_transform, MoveDirection.Left);
break;
case MoveDirection.Up:
_receiver.Move(_transform, MoveDirection.Down);
break;
case MoveDirection.Down:
_receiver.Move(_transform, MoveDirection.Up);
break;
default:
throw new ArgumentOutOfRangeException(nameof(_direction));
}
}
public override string ToString()
{
return _direction.ToString();
}
}
UI Move call - caller
public class UIMoveInvoker
{
private List<ICommand> _commands;
private int _index = -1;
public int Index => _index;
public List<ICommand> CommandList => _commands;
public UIMoveInvoker()
{
_commands = new List<ICommand>();
}
// Execute the move command
public void Move(ICommand command)
{
command.Execute();
// If the command is not the last , Then delete all the following commands
if (_index < _commands.Count - 1)
{
_commands.RemoveRange(_index + 1, _commands.Count - _index - 1);
}
_commands.Add(command);
_index++;
}
// Recovery operation
public void ReDo()
{
if (_index >= _commands.Count - 1) return;
_index++;
_commands[_index].Execute();
}
// Cancel the operation
public void UnDo()
{
if (_index < 0) return;
_commands[_index].Undo();
_index--;
}
}
client ( Use GUI As a visualization )
public class CommandExample : MonoBehaviour
{
[SerializeField] private GUIStyle style;
[SerializeField] private RectTransform rectTransform;
private UIMoveInvoker _invoker;
private void Awake()
{
_invoker = new UIMoveInvoker();
}
private void Update()
{
if (Input.GetKeyDown(KeyCode.W)) _invoker.Move(new MoveCommand(MoveDirection.Up, rectTransform));
else if (Input.GetKeyDown(KeyCode.S)) _invoker.Move(new MoveCommand(MoveDirection.Down, rectTransform));
else if (Input.GetKeyDown(KeyCode.A)) _invoker.Move(new MoveCommand(MoveDirection.Left, rectTransform));
else if (Input.GetKeyDown(KeyCode.D)) _invoker.Move(new MoveCommand(MoveDirection.Right, rectTransform));
else if (Input.GetKeyDown(KeyCode.E)) _invoker.UnDo();
else if (Input.GetKeyDown(KeyCode.R)) _invoker.ReDo();
}
private void OnGUI()
{
var list = _invoker.CommandList;
var index = _invoker.Index;
GUILayout.BeginVertical();
GUILayout.Label((index == -1 ? ">> " : "") + "Start", style);
for (int i = 0; i < list.Count; i++)
{
if (i == index) GUILayout.Label(">> " + list[i].ToString(), style);
else GUILayout.Label(list[i].ToString(), style);
}
GUILayout.EndVertical();
}
}
Running results
explain
Application scenarios
- When the system needs to support commands Revocation and reinstatement when , You can use command mode to store commands .
- When it is necessary to Operation is parameterized when , You can use command mode
- Need to put Requestor and executor are decoupled , Command mode allows the caller not to interact directly .
- When the system needs to perform a set of operations , Command mode can Define macro commands to implement this function .( You can use composite mode to complete a composite command )
Advantages and disadvantages
advantage
- Single responsibility , The caller and implementer are separated .
- When adding a new command , There is no need to modify the client , It satisfies the open close principle
- Undo and restore functions can be realized
- Macro commands can be implemented
shortcoming
- Generate a large number of command classes , Complicate the system
Relationship with other models
- Prototype mode matches command mode , You can save the command
- Combination mode and command mode , You can use a combination command
- The difference between policy mode and command mode , Both are through parameterized objects . Policy mode focuses on context algorithm switching , Describes the different ways in which the purpose is performed . Command mode is to parameterize the operation into commands . By parameterizing the command , To delay the call , Keep records , Send commands, etc .
... Because I haven't finished learning design patterns yet , Other models will not be compared , First write
边栏推荐
- 初识缓存以及ehcache初体验「建议收藏」
- Calculation of torque target value (ftorque) in servo torque control mode
- Big Ben (Lua)
- LeetCode 890(C#)
- How to choose the appropriate automated testing tools?
- Will domestic software testing be biased
- 如何选择合适的自动化测试工具?
- 国内首次!这家中国企业的语言AI实力被公认全球No.2!仅次于谷歌
- Sports Federation: resume offline sports events in a safe and orderly manner, and strive to do everything possible for domestic events
- [tpm2.0 principle and Application guide] Chapter 9, 10 and 11
猜你喜欢
完整的电商系统
Differences between rip and OSPF and configuration commands
6.关于jwt
链式二叉树的基本操作(C语言实现)
Redis
面试唯品会实习测试岗、抖音实习测试岗【真实投稿】
Cadre de validation des données Apache bval réutilisé
Redis cluster and expansion
SlashData开发者工具榜首等你而定!!!
Interview vipshop internship testing post, Tiktok internship testing post [true submission]
随机推荐
POJ 2392 Space Elevator
2022年推荐免费在线接收短信平台(国内、国外)
For friends who are not fat at all, nature tells you the reason: it is a genetic mutation
Tsinghua, Cambridge and UIC jointly launched the first Chinese fact verification data set: evidence-based, covering many fields such as medical society
The live broadcast reservation channel is open! Unlock the secret of fast launching of audio and video applications
10 schemes to ensure interface data security
【Base64笔记】「建议收藏」
Redis publishing and subscription
I feel cheated. Wechat tests the function of "size number" internally, and two wechat can be registered with the same mobile number
[Base64 notes] [suggestions collection]
Kirk borne's selection of learning resources this week [click the title to download directly]
Charles+Postern的APP抓包
How many are there (Lua)
2022.07.05
【剑指 Offer】59 - I. 滑动窗口的最大值
Teach your sister to write the message queue hand in hand
2022.07.04
2022上半年朋友圈都在传的10本书,找到了
2022.07.02
The moveposition function of rigidbody2d of unity2d solves the problem of people or screen jitter when moving