C#设计模式(二)
👉一、责任链模式(Chain of Responsibility)
用于将请求的发送者和接收者解耦,使得多个接收对象都有机会处理同一个请求。当一个请求无法被一个对象处理时,它会沿着一个链传递,直到找到能够处理它的对象为止
责任链模式定义了一个请求的传递和处理过程。具体来说,多个处理器(接收对象)依次处理同一个请求,直到某个处理器能够处理该请求为止。例如,一个采购请求可能会先由管理者处理,如果管理者无法处理,则会传递给副总裁,副总裁再传递给总裁,以此类推
代码如下:
public abstract class Handler
{
private Handler _nextHandler;
public Handler NextHandler
{
get
{
return _nextHandler;
}
set
{
_nextHandler = value;
}
}
public abstract void HandleRequest(int request);
}
public class ConcreteHandlerA : Handler
{
public override void HandleRequest(int request)
{
if (request < 0)
{
Debug.Log("Negative request handled by Handler A");
}
else if (NextHandler != null)
{
NextHandler.HandleRequest(request);
}
}
}
public class ConcreteHandlerB : Handler
{
public override void HandleRequest(int request)
{
if (request > 100)
{
Debug.Log("Request > 100 handled by Handler B");
}
else if (NextHandler != null)
{
NextHandler.HandleRequest(request);
}
}
}
public class ChainOfResponsibilityTest
{
public static void Test()
{
var handlerA = new ConcreteHandlerA();
var handlerB = new ConcreteHandlerB();
handlerA.NextHandler = handlerB;
handlerA.HandleRequest(-1); // handled by Handler A
handlerA.HandleRequest(50); // not handled
handlerA.HandleRequest(150); // handled by Handler B
}
}
👉二、享元模式(Flyweight)
Unity中的享元模式是一种结构型设计模式,旨在通过共享对象来有效支持大量细粒度对象的复用,从而减少内存使用并提升性能。享元模式通过将共享数据集合到一起,并通过少次数调用得到多个实现和复用,从而减少内存占用和提升系统性能。
享元模式通常应用于需要大量相似对象的场景,如游戏中的角色属性设置、UI元素等。通过共享内部状态,可以显著减少内存占用并提升系统性能。
代码如下:
public class Flyweight
{
private string _state;
public Flyweight(string state)
{
_state = state;
}
public void Operation()
{
Debug.Log("Flyweight operation with state: " + _state);
}
}
public class FlyweightFactory
{
private Dictionary<string, Flyweight> _flyweights = new Dictionary<string, Flyweight>();
public Flyweight GetFlyweight(string key)
{
if (!_flyweights.ContainsKey(key))
{
_flyweights.Add(key, new Flyweight(key));
}
return _flyweights[key];
}
}
👉三、解释器模式(Interpreter)
解释器模式用于对语言进行解释,并将其转换成计算机可以处理的形式。在Unity中,解释器模式不常用。
代码如下:
public abstract class AbstractExpression
{
public abstract double Interpret();
}
public class NumberExpression : AbstractExpression
{
private double _number;
public NumberExpression(double number)
{
_number = number;
}
public override double Interpret()
{
return _number;
}
}
public class AdditionExpression : AbstractExpression
{
private AbstractExpression _expression1;
private AbstractExpression _expression2;
public AdditionExpression(AbstractExpression expression1, AbstractExpression expression2)
{
_expression1 = expression1;
_expression2 = expression2;
}
public override double Interpret()
{
return _expression1.Interpret() + _expression2.Interpret();
}
}
public class SubtractionExpression : AbstractExpression
{
private AbstractExpression _expression1;
private AbstractExpression _expression2;
public SubtractionExpression(AbstractExpression expression1, AbstractExpression expression2)
{
_expression1 = expression1;
_expression2 = expression2;
}
public override double Interpret()
{
return _expression1.Interpret() - _expression2.Interpret();
}
}
public class MultiplicationExpression : AbstractExpression
{
private AbstractExpression _expression1;
private AbstractExpression _expression2;
public MultiplicationExpression(AbstractExpression expression1, AbstractExpression expression2)
{
_expression1 = expression1;
_expression2 = expression2;
}
public override double Interpret()
{
return _expression1.Interpret() * _expression2.Interpret();
}
}
public class DivisionExpression : AbstractExpression
{
private AbstractExpression _expression1;
private AbstractExpression _expression2;
public DivisionExpression(AbstractExpression expression1, AbstractExpression expression2)
{
_expression1 = expression1;
_expression2 = expression2;
}
public override double Interpret()
{
return _expression1.Interpret() / _expression2.Interpret();
}
}
public class Interpreter
{
public static void Test()
{
AbstractExpression expression = new AdditionExpression(
new NumberExpression(5),
new MultiplicationExpression(
new NumberExpression(10),
new SubtractionExpression(
new NumberExpression(8),
new NumberExpression(2)
)
)
);
double result = expression.Interpret();
Debug.Log("Interpreter result: " + result);
}
}
👉四、命令模式(Command)
Unity中的命令模式是一种行为型设计模式,它将一个请求封装成一个对象,使得发出请求的责任和执行请求的责任可以分割开。这种方式使得请求的发送者和接收者之间不需要直接交互,从而提高了代码的灵活性和可维护性。例如角色的移动、攻击等
代码如下:
public interface ICommand
{
void Execute();
void Undo();
}
public class MoveCommand : ICommand
{
private Transform _transform;
private Vector3 _direction;
public MoveCommand(Transform transform, Vector3 direction)
{
_transform = transform;
_direction = direction;
}
public void Execute()
{
_transform.position += _direction; // 移动对象
}
public void Undo()
{
_transform.position -= _direction; // 撤销移动
}
}
public class AttackCommand : ICommand
{
private GameObject _target;
public AttackCommand(GameObject target)
{
_target = target;
}
public void Execute()
{
_target.GetComponent<Enemy>().TakeDamage(); // 攻击目标
}
public void Undo()
{
_target.GetComponent<Enemy>().Heal(); // 撤销攻击
}
}
public class CommandInvoker
{
private Stack<ICommand> _commands = new Stack<ICommand>();
public void AddCommand(ICommand command)
{
_commands.Push(command);
command.Execute();
}
public void UndoLastCommand()
{
if (_commands.Count > 0)
{
ICommand command = _commands.Pop();
command.Undo();
}
}
}
👉五、策略模式(Strategy)
策略模式是一种行为设计模式,它定义了一系列的算法,并将每个算法封装成独立的策略类,使得这些算法可以互相替换。策略模式的主要优点在于它允许算法的变化独立于使用这些算法的客户端,从而提高了系统的灵活性和可维护性。
例如:技能系统:在游戏中,角色可能拥有多种技能,每种技能有不同的效果和处理逻辑。通过策略模式,可以动态地切换和执行不同的技能,而不需要修改游戏的其他部分代码。
例如:枪械系统:在射击游戏中,枪械可能有不同的射击行为(如单发、连发、散弹等)。策略模式允许在运行时动态改变枪械的行为,而不需要实例化新的枪械对象。
代码如下:
public interface IStrategy
{
void Execute();
}
public class ConcreteStrategyA : IStrategy
{
public void Execute()
{
Debug.Log("Execute Strategy A");
}
}
public class ConcreteStrategyB : IStrategy
{
public void Execute()
{
Debug.Log("Execute Strategy B");
}
}
public class Context
{
private IStrategy _strategy;
public Context(IStrategy strategy)
{
_strategy = strategy;
}
public void SetStrategy(IStrategy strategy)
{
_strategy = strategy;
}
public void DoAction()
{
_strategy.Execute();
}
}
- 点赞
- 收藏
- 关注作者
评论(0)