What
职责链模式:使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系。将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
Why
首先,为什么要在上下机的时候用职责链?
是因为在上下机的计算金额的时候涉及到多种算钱的方式,我设置了四种方式
如:
当上机时间小于准备时间时,不收费
当上机时间大于准备时间但小于至少上机时间时,收取一定费用
当上机时间大于至少上机时间小于单位时间时,收取单位时间费用
当上机时间大于单位递增时间时,按单位时间收取费用
这就是随着上机时间的变化,逐渐寻找到自己的计算方式,处理金额,这就类似于连成了一条链。
How
B层
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
namespace BLL
{
public abstract class OperateMoneyManager
{
protected OperateMoneyManager successor;
//设置继承者
public void SetSuccessor(OperateMoneyManager successor)
{
this.successor = successor;
}
//处理请求的抽象方法
public abstract void GetMoney(Entity.LineInfo line, Entity.BasicDataInfo basic);
}
public class OperateMoneyOne : OperateMoneyManager
{
public override void GetMoney(Entity.LineInfo line, Entity.BasicDataInfo basic)
{
//当上机时间小于准备时间时,不收费
if (Convert.ToInt32(line.CostTime) <= Convert.ToInt32(basic.PrepareTime))
{
line.CostMoney = Convert.ToString(0);
line.Money = Convert.ToString(Convert.ToInt32(line.Money) - Convert.ToInt32(line.CostMoney));
}
else
{
//转移到下一位
successor.GetMoney(line, basic);
}
}
}
public class OperateMoneyTwo : OperateMoneyManager
{
public override void GetMoney(Entity.LineInfo line, Entity.BasicDataInfo basic)
{
//当上机时间大于准备时间但小于至少上机时间时,收取单位时间费用
if (Convert.ToInt32(line.CostTime) > Convert.ToInt32(basic.PrepareTime) && Convert.ToInt32(line.CostTime) <= Convert.ToInt32(basic.LeastTime))
{
line.CostMoney = Convert.ToString(basic.Rate);
line.Money = Convert.ToString(Convert.ToInt32(line.Money) - Convert.ToInt32(line.CostMoney));
}
else
{
successor.GetMoney(line, basic);
}
}
}
public class OperateMoneyThree : OperateMoneyManager
{
public override void GetMoney(Entity.LineInfo line, Entity.BasicDataInfo basic)
{
//当上机时间大于至少上机时间小于单位时间时,收取单位时间费用
if (Convert.ToInt32(line.CostTime) > Convert.ToInt32(basic.LeastTime) && Convert.ToInt32(line.CostTime) <= Convert.ToInt32(basic.IncreaseTime))
{
line.CostMoney = Convert.ToString(basic.Rate);
line.Money = Convert.ToString(Convert.ToInt32(line.Money) - Convert.ToInt32(line.CostMoney));
}
else
{
successor.GetMoney(line, basic);
}
}
}
public class OperateMoneyFour : OperateMoneyManager
{
public override void GetMoney(Entity.LineInfo line, Entity.BasicDataInfo basic)
{
//当上机时间大于单位递增时间时,按单位时间收取费用
line.CostTime = Convert.ToString(Convert.ToInt32(line.CostTime) - Convert.ToInt32(basic.IncreaseTime));
//有几个单位
int unittime = Convert.ToInt32(line.CostTime) / Convert.ToInt32(basic.IncreaseTime);
line.CostMoney = Convert.ToString(Convert.ToInt32(basic.Rate) + (Convert.ToInt32(basic.Rate) * unittime));
line.Money = Convert.ToString(Convert.ToInt32(line.Money) - Convert.ToInt32(line.CostMoney));
}
}
}
Facade层
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Facade
{
public class OperateMoneyFacade
{
public void Money(Entity.LineInfo line, Entity.BasicDataInfo basic)
{
//实例化
BLL.OperateMoneyManager mOneBll = new BLL.OperateMoneyOne();
BLL.OperateMoneyManager mTwoBll = new BLL.OperateMoneyTwo();
BLL.OperateMoneyManager mThreeBll = new BLL.OperateMoneyThree();
BLL.OperateMoneyFour mFourBll = new BLL.OperateMoneyFour();
//设置职责链上家与下家
mOneBll.SetSuccessor(mTwoBll);
mTwoBll.SetSuccessor(mThreeBll);
mThreeBll.SetSuccessor(mFourBll);
//提交请求
mOneBll.GetMoney(line,basic);
}
}
}
U层
U层负责为B层收集所需要的数据,就比如B层中所用的花费时间,就是在U层中计算获得放到实体层,然后B层再拿来用,以下U层获取花费时间以及原金额的代码
Facade.OperateMoneyFacade FMoney = new Facade.OperateMoneyFacade();
line.DownDate = System.DateTime.Now.ToString("yyyy-MM-dd");
line.DownTime = System.DateTime.Now.ToString("hh:mm:ss");
line.Money = student.Money.ToString();
TimeSpan costtime = Convert.ToDateTime(line.DownTime) - Convert.ToDateTime(txtUpTime.Text);
line.CostTime = Convert.ToString(Convert.ToInt32(costtime.TotalMinutes));
FMoney.Money(line, basic);
总结
我一开始认为用职责链模式后的计费比我之前不用职责链还麻烦,但其实不是这样的,这一处计费可能没什么效果,但是如果有多处用到计费,那就更加体现用职责链模式的好处了。