推荐阅读:

前言

       在开发游戏过程中,当玩家合成一种道具的时候,对于不痛的道具,需要的碎片个数,类型是不同的。用传统的写法,就是使用if...else...语句来判断。如果后面,策划修改了道具合成机制,我们就需要更改if结构判断了,这就违背了设计模式原则中的对扩展的开发,对修改的关闭,为此,我们引入责任链模式。

介绍

       责任链模式(Chain of Responsibility Pattern)为请求创建了一个接收者对象的链。通常每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推。

要素

       1.抽象处理者(Handler):定义出一个处理请求的接口。如果需要,接口可以定义 出一个方法以设定和返回对下家的引用。

       2.具体处理者(ConcreteHandler):具体处理者接到请求后,可以选择将请求处理掉,或者将请求传给下家。由于具体处理者持有对下家的引用,因此,如果需要,具体处理者可以访问下家。

       3.请求类(Request):处理者需要处理的请求信息;

实现

       这里我们还是用上面的例子,使用责任链模式来实现奖品的分发机制。

1.创建请求类

	//请求类,请求合成道具
public class SyntheticRequest
{
/// 当前拥有的碎片数量
public int DebrisNum{ get; set; } public SyntheticRequest(int num)
{
this.DebrisNum= num;
}
}

2.创建抽象角色类

	//抽象角色类,可以通过合成得到的道具
public abstract class Prop
{
//下一级道具,更低一级的道具
public Prop NextProp{ get; set; }
//当前道具类型
public string PropType{ get; set; }
//构造函数
public Prop(string type)
{ this.PropType= type; } /// 该角色的执行行为
public abstract void Behaviour(SyntheticRequest request);
}

3.创建具体角色类

    ///高级道具
public class Prop1:Prop
{
public Prop1(string type) : base(type) { } public override void Behaviour(SyntheticRequest request)
{
if (request.DebrisNum>= 1000)
{
Console.WriteLine("获得{0},消耗{1}碎片", this.PropType,request.DebrisNum);
}
else if (NextProp != null)
{
Console.WriteLine("{0}个碎片不够,只能合成更低一级的道具,即{1}", request.DebrisNum, NextProp.PropType);
NextProp.Behaviour(request);
}
}
}
///中级道具
public class Prop2:Prop
{
public Prop2(string type) : base(type) { } public override void Behaviour(SyntheticRequest request)
{
if (request.DebrisNum>= 500)
{
Console.WriteLine("获得{0},消耗{1}碎片", this.PropType,request.DebrisNum);
}
else if (NextProp != null)
{
Console.WriteLine("{0}个碎片不够,只能合成更低一级的道具,即{1}", request.DebrisNum, NextProp.PropType);
NextProp.Behaviour(request);
}
}
}
///低级道具
public class Prop3:Prop
{
public Prop3(string type) : base(type) { } public override void Behaviour(SyntheticRequest request)
{
if (request.DebrisNum>= 10)
{
Console.WriteLine("获得{0},消耗{1}碎片", this.PropType,request.DebrisNum);
}
else if (NextProp != null)
{
Console.WriteLine("{0}个碎片不够,只能合成更低一级的道具,即{1}", request.DebrisNum, NextProp.PropType);
NextProp.Behaviour(request);
}
}
}

4.使用责任链模式

	//使用责任链模式
class Program
{
static void Main(string[] args)
{
//申请合成道具
SyntheticRequest request= new SyntheticRequest(66); //对该活动的审批可能涉及的角色
Prop prop1= new Prop1("高级道具");
Prop prop2= new Prop2("中级道具");
Prop prop3= new Prop3("低级道具"); //设置责任链
prop1.NextProp = prop2;
prop2.NextProp = prop3; //合成处理
prop1.Behaviour(request);
}
}

整合代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace 责任链模式
{
//请求类,请求合成道具
public class SyntheticRequest
{
/// 当前拥有的碎片数量
public int DebrisNum{ get; set; } public SyntheticRequest(int num)
{
this.DebrisNum= num;
}
} //抽象角色类,可以通过合成得到的道具
public abstract class Prop
{
//下一级道具,更低一级的道具
public Prop NextProp{ get; set; }
//当前道具类型
public string PropType{ get; set; }
//构造函数
public Prop(string type)
{ this.PropType= type; } /// 该角色的执行行为
public abstract void Behaviour(SyntheticRequest request);
} ///高级道具
public class Prop1:Prop
{
public Prop1(string type) : base(type) { } public override void Behaviour(SyntheticRequest request)
{
if (request.DebrisNum>= 1000)
{
Console.WriteLine("获得{0},消耗{1}碎片", this.PropType,request.DebrisNum);
}
else if (NextProp != null)
{
Console.WriteLine("{0}个碎片不够,只能合成更低一级的道具,即{1}", request.DebrisNum, NextProp.PropType);
NextProp.Behaviour(request);
}
}
}
///中级道具
public class Prop2:Prop
{
public Prop2(string type) : base(type) { } public override void Behaviour(SyntheticRequest request)
{
if (request.DebrisNum>= 500)
{
Console.WriteLine("获得{0},消耗{1}碎片", this.PropType,request.DebrisNum);
}
else if (NextProp != null)
{
Console.WriteLine("{0}个碎片不够,只能合成更低一级的道具,即{1}", request.DebrisNum, NextProp.PropType);
NextProp.Behaviour(request);
}
}
}
///低级道具
public class Prop3:Prop
{
public Prop3(string type) : base(type) { } public override void Behaviour(SyntheticRequest request)
{
if (request.DebrisNum>= 10)
{
Console.WriteLine("获得{0},消耗{1}碎片", this.PropType,request.DebrisNum);
}
else if (NextProp != null)
{
Console.WriteLine("{0}个碎片不够,只能合成更低一级的道具,即{1}", request.DebrisNum, NextProp.PropType);
NextProp.Behaviour(request);
}
}
} //使用责任链模式
class Program
{
static void Main(string[] args)
{
//申请合成道具
SyntheticRequest request= new SyntheticRequest(66); //对该活动的审批可能涉及的角色
Prop prop1= new Prop1("高级道具");
Prop prop2= new Prop2("中级道具");
Prop prop3= new Prop3("低级道具"); //设置责任链
prop1.NextProp = prop2;
prop2.NextProp = prop3; //合成处理
prop1.Behaviour(request);
}
}
}

优缺点

优点:

       降低了请求的发送者和接收者之间的耦合;把多个条件判定分散到各个处理类中,使得代码更加清晰,责任更加明确。

缺点:

       在找到正确的处理对象之前,所有的条件判定都要执行一遍,当责任链过长时,可能会引起性能的问题;可能导致某个请求不被处理。

总结

       代码中存在多个if-else语句的情况下,此时可以考虑使用责任链模式来对代码进行重构。

注意

       这里举的例子,在实际开发过程中可能不会用到设计模式,希望各位读者切勿固步自封。

设计模式(C#)——12责任链模式的更多相关文章

  1. Python使用设计模式中的责任链模式与迭代器模式的示例

    Python使用设计模式中的责任链模式与迭代器模式的示例 这篇文章主要介绍了Python使用设计模式中的责任链模式与迭代器模式的示例,责任链模式与迭代器模式都可以被看作为行为型的设计模式,需要的朋友可 ...

  2. Java设计模式学习记录-责任链模式

    前言 已经把五个创建型设计模式和七个结构型设计模式介绍完了,从这篇开始要介绍行为型设计模式了,第一个要介绍的行为型设计模式就是责任链模式(又称职责链模式). 责任链模式 概念介绍 责任链模式是为了避免 ...

  3. 《java设计模式》之责任链模式

    在阎宏博士的<JAVA与模式>一书中开头是这样描述责任链(Chain of Responsibility)模式的: 责任链模式是一种对象的行为模式.在责任链模式里,很多对象由每一个对象对其 ...

  4. 《JAVA设计模式》之责任链模式(Chain of Responsibility)

    在阎宏博士的<JAVA与模式>一书中开头是这样描述责任链(Chain of Responsibility)模式的: 责任链模式是一种对象的行为模式.在责任链模式里,很多对象由每一个对象对其 ...

  5. 重学 Java 设计模式:实战责任链模式「模拟618电商大促期间,项目上线流程多级负责人审批场景」

    作者:小傅哥 博客:https://bugstack.cn - 原创系列专题文章 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 场地和场景的重要性 射击

  6. [设计模式] javascript 之 责任链模式

    责任链模式:定义 责任链接模式又称职责链模式,是一种对象的行为模式:它是一种链式结构,每个节点都有可能两种操作,要么处理该请求停止该请求操作,要么把请求转发到下一个节点,让下一个节点来处理请求:该模式 ...

  7. Java设计模式系列之责任链模式

    责任链模式 责任链模式是一种对象的行为模式.在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链.请求在这个链上传递,直到链上的某一个对象决定处理此请求.发出这个请求的客户端并不知道 ...

  8. 设计模式学习之责任链模式(Chain of Responsibility,行为型模式)(22)

    参考:http://www.cnblogs.com/zhili/p/ChainOfResponsibity.html 一.引言 在现实生活中,有很多请求并不是一个人说了就算的,例如面试时的工资,低于1 ...

  9. Java描述设计模式(15):责任链模式

    本文源码:GitHub·点这里 || GitEE·点这里 一.生活场景描述 1.请假审批流程 公司常见的请假审批流程:请假天数 当 day<=3 天,项目经理审批 当 3<day<= ...

随机推荐

  1. 【微信小程序】微信小程序-实现tab

    一.前言 小程序开发中,有很多封装好的控件供开发者使用,但是,很常见的tab选项卡居然没有,只能自己搞一个. 实现原理也很简单,无非是用给view(tab)设置一个点击事件bintap,并且给view ...

  2. 仿制shazzam的简单功能,将hlsl转换为WPF中的ShaderEffect

    (此文章只是在对WPF的Effect产生兴趣才稍微研究了一点后面的知识;需要了解更多可参考https://archive.codeplex.com/?p=shazzam的源代码以及WPF基础知识) 1 ...

  3. 手撸PHP数据库连接

    最近这个月过得确实有点狼狈....不停地复习,看书..终于到今天为止考完了2科了.能让我好好地写写博客了..前段时间的PHP课设我多学了点东西,在我们一般老师讲的php连接数据库方面做了一些优化.前段 ...

  4. 实现跳转的jsp小例子

    <%@page import="java.io.UnsupportedEncodingException"%> <%@ page language="j ...

  5. RabbitMQ搭建单机及集群

    1,基本环境配置 hosts 文件 免密登录 2,访问官网 https://www.rabbitmq.com/download.html 3, 4,安装依赖 yum -y install make g ...

  6. angular6组件封装以及发布到npm

    一.创建angular项目 ng new myFirstDemo //angular-cli新建项目ng g m testm //新建模块ng g c testm/headertest //新建组件 ...

  7. CSS开启硬件加速来提高网站性能

    原文永久链接 CSS animations, transforms 以及 transitions 不会自动开启GPU加速,而是由浏览器的缓慢的软件渲染引擎来执行. 那我们怎样才可以切换到GPU模式呢, ...

  8. 用mongodb 固定集合实现只保留固定数量的记录,自动淘汰老旧数据

    在一个保存report记录的场景中,我们使用MongoDB进行数据存储 example: db: report Collection: daily_report 创建db:  use report; ...

  9. Mysql的行级锁与表级锁

    在计算机科学中,锁是在执行多线程时用于强行限制资源访问的同步机制,即用于在并发控制中保证对互斥要求的满足. 在DBMS中,可以按照锁的粒度把数据库锁分为行级锁(INNODB引擎).表级锁(MYISAM ...

  10. JDK1.8源码分析01之学习建议(可以延伸其他源码学习)

    序言:目前有个计划就是准备看一下源码,来提升自己的技术实力.同时现在好多面试官都喜欢问源码,问你是否读过JDK源码等等? 针对如何阅读源码,也请教了我的老师.下面就先来看看老师的回答,也许会有帮助呢. ...