在机房收费系统中自我感觉上机是需要条件判断最多的一个功能,要判断:1、卡号是否存在;2、密码是否正确;3、该卡是否能用;4、该卡是否已经上机;5、卡里面是不是有钱。暂时仅我自己就能想到了这么多判断,如果还是按照以前的写法的话,要写多少的if...else...呢,全都罗列在一起也不符合面向对象的思想,所以,就可以用到状态模式来解决这个问题。
状态模式
当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。
它主要解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况,把状态的判断逻辑转移到表示不同状态的一系列类当中,可以把复杂的判断逻辑简化。
好处:
将与特定状态相关的行为局部化,并且将不同状态的行为分割开来。目的是消除庞大的条件分支语句,状态模式通过把各种状态转移逻辑分布到State的子类之间,来减少相互间的依赖。
状态模式结构图:
机房收费系统上机中的状态模式:
从类图可以看出,我定义了一个抽象状态类,五个具体状态类和一个实例维护类。
上机抽象类:
public abstract class CardOnlineState
{
public abstract void Online(CardOnlineContext context,CardEntity cardentity, LineInfoEntity LineInfoEntity, BasicDataEntity BasicDataEntity);
}
上机条件判断具体状态类:
public class IsExitCard : CardOnlineState
{
public override void Online(CardOnlineContext context,CardEntity cardentity, LineInfoEntity LineInfoEntity, BasicDataEntity BasicDataEntity)
{
//检查卡号是否存在方法
Factory.FactoryDB factory = new Factory.FactoryDB(); //实例化工厂
ICard ICard = factory.CreateICard(); //创建接口
List<CardEntity> list = ICard.IsExitCardNo(cardentity); //通过接口调D层方法
if (list.Count == 0)
{
throw new Exception("该卡号不存在,无法上机!");
}
else
{
context.CardOnlineState = new CheckPwd(); //设置下一状态,即CheckPwd
}
}
}
public class CheckPwd : CardOnlineState
{
public override void Online(CardOnlineContext context, CardEntity cardentity, LineInfoEntity LineInfoEntity, BasicDataEntity BasicDataEntity)
{
//检查该卡是否上机方法
Factory.FactoryDB factory = new Factory.FactoryDB();
ICard ICard = factory.CreateICard();
List<CardEntity> list = ICard.CheckStuPwd(cardentity);
if (list.Count == 0)
{
throw new Exception("密码不正确,无法上机!");
}
else
{
context.CardOnlineState = new IsCardUse(); //设置下一状态,即IsCardUse
}
}
}
public class IsCardUse : CardOnlineState
{
public override void Online(CardOnlineContext context, CardEntity cardentity, LineInfoEntity LineInfoEntity, BasicDataEntity BasicDataEntity)
{
//检查该卡是否使用方法
Factory.FactoryDB factory = new Factory.FactoryDB();
ICard ICard = factory.CreateICard();
List<CardEntity> list = ICard.IsCardUse(cardentity);
if (list.Count == 0)
{
throw new Exception("此卡已销,无法上机!");
}
else
{
context.CardOnlineState = new IsOnline(); //设置下一状态,即IsOnline
}
}
}
public class IsOnline : CardOnlineState
{
public override void Online(CardOnlineContext context, CardEntity cardentity, LineInfoEntity LineInfoEntity, BasicDataEntity BasicDataEntity)
{
//判断该卡是否已经上机方法
Factory.FactoryDB factory = new Factory.FactoryDB();
ILineInfo ILineInfo = factory.CreateILineInfo();
List<LineInfoEntity> list = ILineInfo.IsStuOnLine(LineInfoEntity);
if (list.Count != 0)
{
throw new Exception("此卡正在上机,上机失败!");
}
else
{
context.CardOnlineState = new IsLeastCash(); //设置下一状态,即IsLeastCash
}
}
}
public class IsLeastCash : CardOnlineState
{
public override void Online(CardOnlineContext context, CardEntity cardentity, LineInfoEntity LineInfoEntity, BasicDataEntity BasicDataEntity)
{
//判断卡内是否有钱上机方法
Factory.FactoryDB factory = new Factory.FactoryDB();
ICard ICard = factory.CreateICard();
List<CardEntity> list = ICard.InquireBalance(cardentity);
Factory.FactoryDB factory1 = new Factory.FactoryDB();
IBasicData IBasicData = factory1.CreateIBasicData();
List<BasicDataEntity> list1 = IBasicData.InquireBasicData(BasicDataEntity);
if (list[0].Cash < list1[0].LeastCash)
{
throw new Exception("此卡余额不足,上机失败!");
}
}
}
维护状态类的实例:
public class CardOnlineContext
{
//定义维护类初始状态
private CardOnlineState cardonlinestate;
public CardOnlineContext(CardOnlineState cardonlinestate)
{
this.cardonlinestate = cardonlinestate;
}
//可读写的状态属性,用于读取当前状态和设置新状态
public CardOnlineState CardOnlineState
{
get { return cardonlinestate; }
set { cardonlinestate = value; }
}
//对请求处理,并设置下一状态
public void SetState(CardEntity cardentity, LineInfoEntity LineInfoEntity, BasicDataEntity BasicDataEntity)
{
cardonlinestate.Online(this,cardentity,LineInfoEntity, BasicDataEntity);
}
}
调用:
public void LineLogin(CardEntity cardentity, LineInfoEntity LineInfoEntity, BasicDataEntity BasicDataEntity)
{
#region 状态模式实现上机
//设置维护实例类初始状态,即IsexitCard
CardOnlineContext c1 = new CardOnlineContext(new IsExitCard()); //判断卡号是否存在
//下面是不断的请求
c1.SetState(cardentity, LineInfoEntity, BasicDataEntity);
c1.SetState(cardentity, LineInfoEntity, BasicDataEntity);
c1.SetState(cardentity, LineInfoEntity, BasicDataEntity);
c1.SetState( cardentity, LineInfoEntity, BasicDataEntity);
c1.SetState(cardentity, LineInfoEntity, BasicDataEntity);
#endregion
}
关于状态模式的运用也是磕磕绊绊的过来的,曾一度被改的面目全非,但一遍一遍的调试对设计模式的理解也就愈发深刻,最终还是成功运行出来了,所以,要大胆去做,不去做又怎么会知道成功就在不远的拐角处呢?