机房合作中在下机的过程中我们加入了策略和职责链模式,整体思路是这样的:从U层把基本数据和学生上机时界面信息传到Facade层;Facade层将Entity.Basic和Entity.Line传递到B层,根据策略模式判断固定用户还是临时用户返回单位时间收费金额值;再从Facade中将返回的时间收费金额值作为Line实体的一部分,将Entity.Basic和Entity.Line传递到B层,根据职责链模式计算花费的金额。
策略模式
概念:它定义了算法家族,分别封装起来,让他们之间互相替换,此模式让算法的变化不会影响到算法的客户。
应用:根据用户的不同,通过策略模式让它返回不同用户的单位收费金额。
Facade:向B层传递实体
public class facOffLine
{
public Entity.Line UpdateBill(Line enLine, BasicData enData)
{
//策略模式计算不同用户单位时间收费金额
BLL.策略模式.bllCashContext cssuper = new BLL.策略模式.bllCashContext(enLine);
//传递实体到B层,返回值为实体
enData.consumeTypeCash = cssuper.getResult(enData);
}
}
bllCashContext:申明此类,Facade只识别此类
public class bllCashContext
{
bllCashSuper cs = null;
/// <summary>
/// 根据不同类型实例化不同类
/// </summary>
/// <param name="enLine"></param>
/// <returns></returns>
public bllCashContext(Line enLine)
{
switch (enLine.type)
{
case "固定用户":
cs = new bllFixedUser();
break;
case "临时用户":
cs = new bllTempUser();
break;
}
}
/// <summary>
/// 实现Facade传递过来的方法,返回为实体
/// </summary>
/// <param name="enData"></param>
/// <returns></returns>
public decimal getResult(BasicData enData)
{
return cs.acceptCash(enData);
}
}
bllCashSuper:定义实现固定用户或临时用户的父类
/// <summary>
/// 根据类型返回每小时金额
/// </summary>
abstract class bllCashSuper
{
public abstract decimal acceptCash( BasicData enData);
}
bllFixedUser:子类固定用户方法
class bllFixedUser:bllCashSuper
{
public override decimal acceptCash( Entity.BasicData enData)
{
//计算固定用户单位收费金额
enData.consumeTypeCash = enData.regularUser/60*Convert.ToDecimal(enData.unitTime);
return enData.consumeTypeCash;
}
}
bllTempUser:子类临时用户方法
class bllTempUser:bllCashSuper
{
public override decimal acceptCash(Entity.BasicData enData)
{
//计算临时用户单位收费金额
enData.consumeTypeCash = enData.tempUser / 60 * Convert.ToDecimal(enData.unitTime);
return enData.consumeTypeCash;
}
}
职责链模式
概念:使多个对象都有机会处理请求,从而避免发送请求的发送者和接受者之间的耦合关系。将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它。
应用:根据消费时间是<准备时间,<最少上机时间,大于最少上机时间,分为三种情况金鑫处理,把处理过程组成一条链,寻找可以处理它的方法。
Facade:传递实体到B层
public class facOffLine
{
public Entity.Line UpdateBill(Line enLine, BasicData enData)
{
//策略模式计算不同用户单位时间收费金额
BLL.策略模式.bllCashContext cssuper = new BLL.策略模式.bllCashContext(enLine);
//传递实体到B层,返回值为实体
enData.consumeTypeCash = cssuper.getResult(enData);
//职责链计算消费金额
BLL.职责链.bllFirstCash FirstCash = new BLL.职责链.bllFirstCash();
BLL.职责链.bllSecondCash SecondCash = new BLL.职责链.bllSecondCash();
BLL.职责链.bllThirdCash ThirdCash = new BLL.职责链.bllThirdCash();
FirstCash.SetSuperior(SecondCash); //设置第二继承者
SecondCash.SetSuperior(ThirdCash); //设置第三继承者
//初始设定第一继承者
FirstCash.CountCash(enLine, enData);
//返回实体
return enLine;
}
}
public abstract class bllCountCash
{
protected bllCountCash superior;
//设置继承者
public void SetSuperior(bllCountCash superior)
{
this.superior = superior;
}
//计算步骤
abstract public Entity.Line CountCash(Line enLine, BasicData enData);
}
public class bllFirstCash:bllCountCash
{
/// <summary>
/// 继承父类
/// </summary>
/// <param name="enLine"></param>
/// <param name="enData"></param>
/// <returns></returns>
public override Entity.Line CountCash(Line enLine,BasicData enData)
{
//如果消费时间<准备时间,消费金额为0
if (enLine.consumeTime<enData.prepareTime)
{
enLine.consumeCash = 0;
}
else
{
//否则转接到下一个类中进行计算
superior.CountCash(enLine, enData);
}
//返回实体enLine
return enLine;
}
}
public class bllSecondCash : bllCountCash
{
/// <summary>
/// 继承父类
/// </summary>
/// <param name="enLine"></param>
/// <param name="enData"></param>
/// <returns></returns>
public override Entity.Line CountCash(Entity.Line enLine, Entity.BasicData enData)
{
//如果消费时间<最小上机时间,消费金额为单位消费金额
if (enLine.consumeTime < enData.leastTime )
{
enLine.consumeCash = enData.consumeTypeCash;
}
else
{
//否则转接到下一个类中进行计算
superior.CountCash(enLine, enData);
}
//返回实体enLine
return enLine;
}
}
bllThirdCash://如果消费时间>单位最小上机时间,分情况计算
public class bllThirdCash:bllCountCash
{
/// <summary>
/// 继承父类
/// </summary>
/// <param name="enLine"></param>
/// <param name="enData"></param>
/// <returns></returns>
public override Entity.Line CountCash(Entity.Line enLine, Entity.BasicData enData)
{
//如果消费时间>单位最小上机时间
if (enLine.consumeTime > enData.leastTime)
{
//如果取余为0
if ( (enLine.consumeTime % enData.unitTime)>0)
{
//消费金额=单位消费金额*(消费时间/单位递增时间+1)
enLine.consumeCash = enData.consumeTypeCash *(enLine.consumeTime / enData.unitTime+1);
}
else
{
//消费金额=单位消费金额*(消费时间/单位递增时间)
enLine.consumeCash = enData.consumeTypeCash * enLine.consumeTime/enData.unitTime;
}
}
//返回实体enLine
return enLine;
}
}
小结
其实感觉他们两个在计算消费金额的时候使用一个就可以,但是为了应用模式就这样写,算是练手吧。以后对于一些大的项目应用设计模式做一个铺垫。
现在真实的感受到机房收费三遍,每一遍的意义和收获,这虽然是一个不是很复杂的系统,但是里面包含的内容却很多,每一遍都需要我们认真去做,然后总结。