unity几种设计模式(自用)
unity的几种设计模式
- 1.单例模式
- 2.观察者模式
- 3.工厂模式
- 4.状态模式
- 5.命令模式
1.单例模式
public class GameManager : MonoBehaviour
{
public static GameManager Instance { get; private set; }
void Awake()
{
if (Instance == null)
{
Instance = this;
DontDestroyOnLoad(gameObject);
}
else
{
Destroy(gameObject);
}
}
}
确保全局的一个类只有一个实例。非静态的方法也可以像静态函数那样使用了。
2.观察者模式
using System;
public class Kettle
{
public delegate void BoilingHandler(string message);
// 定义事件,基于自定义委托 BoilingHandler
public event BoilingHandler OnBoiling;
// 烧水方法
public void BoilWater()
{
Console.WriteLine("Kettle: Water is boiling...");
OnBoiling?.Invoke("The water is boiling!"); // 触发事件
}
}
public class Person
{
public string Name { get; }
public Person(string name)
{
Name = name;
}
// 事件处理方法
public void HandleBoiling(string message)
{
Console.WriteLine($"{Name} received a message: {message}");
}
}
class Program
{
static void Main(string[] args)
{
// 创建水壶对象
Kettle kettle = new Kettle();
// 创建观察者(人)
Person alice = new Person("Alice");
Person bob = new Person("Bob");
// 订阅事件
kettle.OnBoiling += alice.HandleBoiling;
kettle.OnBoiling += bob.HandleBoiling;
// 烧水
kettle.BoilWater();
// 取消订阅(可选)
kettle.OnBoiling -= bob.HandleBoiling;
// 再次烧水
Console.WriteLine("\nBob unsubscribed. Boiling again...");
kettle.BoilWater();
}
}
当观察者观察的对象出现变化满足某种条件时,记录变化,所有依赖它的对象都会收到通知。
比如:角色受伤->通知UI显示
水烧开了->通知报警器和显示器
角色死亡了->通知控制器和游戏结束UI
逻辑:在被观察者类里面新建事件和事件的调用,订阅观察者类里的某些函数,达到某种要求通知所有观察者。
3.工厂模式
1. 定义产品接口
首先,我们定义一个 IShape 接口(也可以使用抽象类和抽象方法),所有具体的形状类都需要实现这个接口。
public interface IShape
{
void Draw();
}
2. 定义新产品
public class Circle : IShape
{
public void Draw()
{
Console.WriteLine("Drawing a Circle.");
}
public void Print();
}
public class Rectangle : IShape
{
public void Draw()
{
Console.WriteLine("Drawing a Rectangle.");
}
}
3. 工厂类
public class ShapeFactory
{
public IShape CreateShape(string shapeType)
{
if (shapeType.Equals("Circle", StringComparison.OrdinalIgnoreCase))
{//比较字符串, 忽略大小写因素
return new Circle();
}
else if (shapeType.Equals("Rectangle", StringComparison.OrdinalIgnoreCase))
{
return new Rectangle();
}
else
{
throw new ArgumentException("Invalid shape type.");
}
}
}
4. 使用工厂
using System;
class Program
{
static void Main(string[] args)
{
ShapeFactory shapeFactory = new ShapeFactory();
// 创建圆形
IShape circle = shapeFactory.CreateShape("Circle");
circle.Draw();
// 创建矩形
IShape rectangle = shapeFactory.CreateShape("Rectangle");
rectangle.Draw();
// 尝试创建不支持的形状
try
{
IShape unknownShape = shapeFactory.CreateShape("Triangle");
unknownShape.Draw();
}
catch (ArgumentException ex)
{
Console.WriteLine(ex.Message);
}
}
}
一般都是写一个接口里面包含各种方法,继承的子类必须完成这些函数的实现,也可以再此基础上扩展。
4.状态模式
和状态机一模一样。
5.命令模式
实现命令接口类对应几种不同的命令
using UnityEngine;
using System.Collections.Generic;
// 命令接口
public interface ICommand
{
void Execute();
void Undo();
}
// 具体命令类:向前移动
public class MoveForwardCommand : ICommand
{
private Transform _transform;
private Vector3 _previousPosition;
public MoveForwardCommand(Transform transform)
{
_transform = transform;
}
public void Execute()
{
_previousPosition = _transform.position;
//记录当前命令执行的位置
_transform.Translate(Vector3.forward * Time.deltaTime);
}
public void Undo()
{
_transform.position = _previousPosition;
}
}
命令调用者:
public class CommandInvoker
{
private Stack<ICommand> _commandHistory = new Stack<ICommand>();
public void ExecuteCommand(ICommand command)
{
command.Execute();
_commandHistory.Push(command);
}
public void UndoLastCommand()
{
if (_commandHistory.Count > 0)
{
ICommand lastCommand = _commandHistory.Pop();
//移除并返回栈顶
lastCommand.Undo();
}
}
}
主函数:
public class CommandExample : MonoBehaviour
{
private CommandInvoker _invoker;
private void Start()
{
_invoker = new CommandInvoker();
}
private void Update()
{
if (Input.GetKeyDown(KeyCode.W))
{
ICommand moveForwardCommand = new MoveForwardCommand(transform);
_invoker.ExecuteCommand(moveForwardCommand);
}
else if (Input.GetKeyDown(KeyCode.S))
{
ICommand moveBackwardCommand = new MoveBackwardCommand(transform);
_invoker.ExecuteCommand(moveBackwardCommand);
}
else if (Input.GetKeyDown(KeyCode.Z))
{
_invoker.UndoLastCommand();
}
}
}