当前位置:网站首页>责任链模式 - Unity
责任链模式 - Unity
2022-07-07 15:38:00 【有趣就行】
责任链模式
责任链模式是对象行为型模式,该模式中请求者发送的请求需要沿着处理者链进行传递,并被处理者处理,这样可以避免请求发送者与多个处理者耦合。
责任链中,将处理请求的行为独立成对象,通过链的结构将所有行为串联起来。这样的结构十分常见,如银行的业务处理流程,公司采购流程等,它们都是属于这样的结构。还有一种更为常见的形式,就是处理者在接受请求时,可以决定是否处理或交给下一个处理者处理,所有每个请求者最多有一个处理者进行处理,要么就没有处理者处理。
结构
说明
- 抽象处理者(Handler)- 定义所有处理请求的接口,其中还包含一个后续连接。
- 基础处理者(Base Handler,可选)- 提取所有具体处理者的代码公有部分,如执行判断,执行,设置下个后继点等,本身是为了提高代码复用率。
- 具体处理者(Concrete Handler)- 实现请求处理的方法,判断是否处理本次请求,是否将请求传给下个后继点。
实现
根据怒气值来释放不同的技能。
技能枚举
public enum AngerSkill
{
None,
One,
Two,
Three,
}
处理者接口
public interface IHandler
{
IHandler NextHandler {
set; }
AngerSkill Release(int angleValue);
}
基础处理者
public abstract class BaseHandler : IHandler
{
private IHandler _nextHandler;
//实现后继节点方法
public IHandler NextHandler
{
set => _nextHandler = value;
}
//使用了模板方法模式,定义算法流程,具体实现分配到子类
public AngerSkill Release(int angerValue)
{
if (IsAllow(angerValue))
return Realization();
return _nextHandler?.Release(angerValue) ?? AngerSkill.None;
}
//实现行为的方法
protected abstract AngerSkill Realization();
//判断是否可以执行此行为的条件
protected abstract bool IsAllow(int angerValue);
}
技能处理者 - 具体处理者
//技能一
public class AngerSkillOne : BaseHandler
{
protected override AngerSkill Realization() => AngerSkill.One;
protected override bool IsAllow(int angerValue) => angerValue > 10 && angerValue < 30;
}
//技能二
public class AngerSkillTwo : BaseHandler
{
protected override AngerSkill Realization() => AngerSkill.Two;
protected override bool IsAllow(int angerValue) => angerValue >= 30 && angerValue < 60;
}
//技能三
public class AngerThree : BaseHandler
{
protected override AngerSkill Realization() => AngerSkill.Three;
protected override bool IsAllow(int angerValue) => angerValue >= 60;
}
技能工厂(负责创建,生成责任链,连接相关节点)
public class AngerSkillFactory
{
public static IHandler CreateSkill()
{
IHandler skill1 = new AngerSkillOne();
IHandler skill2 = new AngerSkillTwo();
IHandler skill3 = new AngerThree();
skill1.NextHandler = skill2;
skill2.NextHandler = skill3;
return skill1;
}
}
调用端
public class ResponsibiltyExample : MonoBehaviour
{
private IHandler _skill;
private InputField _inputField;
private TMP_Text _text;
private void Awake()
{
_skill = AngerSkillFactory.CreateSkill();
_inputField = GetComponentInChildren<InputField>();
_text = GetComponentInChildren<TMP_Text>();
_inputField.onEndEdit.AddListener(ActivateSkills);
}
private void ActivateSkills(string angerValue)
{
if (!int.TryParse(angerValue, out int value)) return;
var angerSkill = _skill.Release(value);
_text.text = angerSkill switch
{
AngerSkill.None => "Lack Of Anger",
AngerSkill.One => "Skill One",
AngerSkill.Two => "Skill Two",
AngerSkill.Three => "Skill Three",
_ => throw new ArgumentOutOfRangeException()
};
}
}
应用场景
- 当一个请求需要多个处理者共同处理时,属于一对多情况下,使用责任链模式。
- 需要按顺序来进行处理时。
- 处理者和处理顺序需要动态改变
- 请求由一个处理者执行,但处理者有多个,请求需要在链上寻找可以执行的处理者。
优缺点
优点
- 可以自由选择执行流程(有点像链表)
- 发起操作和执行操作的类解耦,单一职责原则
- 无需修改客户端,便添加新的职责,开闭原则
缺点
- 部分请求可能出现未被处理的情况
- 对于长的责任链,请求处理涉及多个处理对象,系统速度降低
与其他模式关系
- 责任链 与 命令 都是请求者与实现者之间的连接。责任链是一对多,将请求动态的传递到每个可能的处理者种,直至被处理或处理完毕为止。命令是一对一的单向连接,且通过参数化命令,来灵活的处理请求者和实现者的行为。
- 责任链 和 装饰 类结构十分相似,两者都是依赖组合将执行操作传递给一系列对象。责任链的处理对象具有独立性,且可以随时停止传递。装饰对象是在扩展原有方法的行为,且无法中断。
- 责任链 和 组合 模式一起使用,可以将请求沿包含全体父组件的链一直传递至对象树的底部。
- 责任链的连接可以使用 工厂模式 进行创建
- 责任链 和 模板方法 一起使用,可以提取处理者公有的流程行为,提高代码的复用。
边栏推荐
- LeetCode 152. Product maximum subarray daily question
- LeetCode 1186. 删除一次得到子数组最大和 每日一题
- Skimage learning (3) -- adapt the gray filter to RGB images, separate colors by immunohistochemical staining, and filter the maximum value of the region
- [fan Tan] those stories that seem to be thinking of the company but are actually very selfish (I: building wheels)
- Flask搭建api服务-生成API文档
- How to add aplayer music player in blog
- The process of creating custom controls in QT to encapsulating them into toolbars (II): encapsulating custom controls into toolbars
- 第九届 蓝桥杯 决赛 交换次数
- 【Seaborn】组合图表:FacetGrid、JointGrid、PairGrid
- Process from creation to encapsulation of custom controls in QT to toolbar (I): creation of custom controls
猜你喜欢
Share the latest high-frequency Android interview questions, and take you to explore the Android event distribution mechanism
skimage学习(3)——使灰度滤镜适应 RGB 图像、免疫组化染色分离颜色、过滤区域最大值
Sator launched Web3 game "satorspace" and launched hoobi
SIGGRAPH 2022最佳技术论文奖重磅出炉!北大陈宝权团队获荣誉提名
Matplotlib绘制三维图形
QT中自定义控件的创建到封装到工具栏过程(一):自定义控件的创建
The process of creating custom controls in QT to encapsulating them into toolbars (II): encapsulating custom controls into toolbars
如何选择合适的自动化测试工具?
NeRF:DeepFake的最终替代者?
Seaborn数据可视化
随机推荐
Nerf: the ultimate replacement for deepfake?
The top of slashdata developer tool is up to you!!!
rpcms获取指定分类下的文章的方法
LeetCode 1696. Jumping game VI daily question
SlashData开发者工具榜首等你而定!!!
Lex & yacc of Pisa proxy SQL parsing
【Seaborn】组合图表:FacetGrid、JointGrid、PairGrid
How to mount the original data disk without damage after the reinstallation of proxmox ve?
如何在博客中添加Aplayer音乐播放器
With the latest Alibaba P7 technology system, mom doesn't have to worry about me looking for a job anymore
Number of exchanges in the 9th Blue Bridge Cup finals
LeetCode 1696. 跳跃游戏 VI 每日一题
User defined view essential knowledge, Android R & D post must ask 30+ advanced interview questions
LeetCode 213. Home raiding II daily question
The process of creating custom controls in QT to encapsulating them into toolbars (II): encapsulating custom controls into toolbars
Smart logistics platform: make overseas warehouses smarter
LeetCode 1049. Weight of the last stone II daily question
Mrs offline data analysis: process OBS data through Flink job
From Devops to mlops: how do it tools evolve to AI tools?
服务器彻底坏了,无法修复,如何利用备份无损恢复成虚拟机?