引言:
之前老师说过遇到问题尽量不要看提高班同学写的博客,太有针对性,现在发现即使看了这些博客,也不一定能弄得出来,真的是太考验我们的逻辑和耐心,经过这几天的研究在上机的时候用上了状态模式。
简介:
上机的时候需要判断卡号是否存在、是否使用、是否正在上机、余额是否大于至少消费金额,这一系列的判断可以运用状态模式。
定义:
状态模式(State):当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。
状态模式主要解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同状态的一系列类当中,可以把复杂的判断逻辑化。
UML图:
实现:
在B层加了一个文件夹来写状态模式,写了四个类:context类、state类和uml图中是对应的,我把三个具体状态类写到一个类中了OnLineState类,另外我加了一个类OnLineLogin,用这个类进行调用。
Context类:
namespace BLL.State
{
//维护具体状态类
public class Context
{
private State state;
//定义Context的初始状态
public Context(State state)
{
this.state = state;
}
//可读写的状态属性,用于读取当前状态和设置新状态
public State State
{
get { return state; }
set { state = value; }
}
//对请求处理,并设置下一个状态
public void SetState(CardInfo eCard, OnOffLineInfo eOnOffLine, BasicDataInfo eBasicData)
{
state.Online(this,eCard, eOnOffLine, eBasicData);
}
}
}
State类:
namespace BLL.State
{
public abstract class State
{
public abstract void Online(Context context, CardInfo eCard, OnOffLineInfo eOnOfflline, BasicDataInfo eBasicData);
}
}
OnLineState类:
namespace BLL.State
{
public class IsCardUse:State
{
public override void Online(Context context, CardInfo eCard, OnOffLineInfo eOnOfflline, BasicDataInfo eBasicData)
{
//判断卡是否使用
Interface.ICardDAO ICard;
ICard = Factory.CardFactory.Card();
List<CardInfo> mylist =ICard.SelectCardNo (eCard);
if (mylist.Count == 0)
{
throw new Exception("此卡已销,无法上机!");
}
else
{
//设置下一状态
//Context context=new Context(state);
context.State= new IsOnLine();
}
}
}
public class IsOnLine : State
{
public override void Online(Context context, CardInfo eCard, OnOffLineInfo eOnOfflline, BasicDataInfo eBasicData)
{
Interface.IOnOffLineDAO IOnOffLine;
IOnOffLine = Factory.OnOffLineFactory.OnOffLine();
List<OnOffLineInfo> mylist = IOnOffLine.SelectState (eOnOfflline);
if (mylist.Count != 0)
{
throw new Exception("此卡正在上机!");
}
else
{
//设置下一状态
context.State = new IsLeastCash();
}
}
}
public class IsLeastCash : State
{
public override void Online(Context context, CardInfo eCard, OnOffLineInfo eOnOfflline, BasicDataInfo eBasicData)
{
//判断卡内是少于最少消费金额
Interface.ICardDAO ICard;
ICard = Factory.CardFactory.Card();
List<CardInfo> mylistCard = ICard.SelectCardNo (eCard);
Interface.IBasicDataDAO IBasicData;
IBasicData = Factory.BasicDataFactory.BasicData();
List<BasicDataInfo> mylistData = IBasicData.SelectBasicData();
if (mylistCard [0].Cash <mylistData[0].LeastCash )
{
throw new Exception("此卡余额不足,上机失败!");
}
}
}
}
调用:
B层OnLineLogin类:
namespace BLL.State
{
public class OnLineLogin
{
public void OnLine(CardInfo eCardInfo, OnOffLineInfo eOnOffLineInfo, BasicDataInfo eBasicDataInfo)
{
//设置维护实例类初始状态,即IsCardUse判断卡号是否使用
Context state = new Context(new IsCardUse());
//进行请求
state.SetState(eCardInfo , eOnOffLineInfo ,eBasicDataInfo);
state.SetState(eCardInfo, eOnOffLineInfo, eBasicDataInfo);
state.SetState(eCardInfo, eOnOffLineInfo, eBasicDataInfo);
}
}
}
外观层:
//外观层调用B层,实现状态模式
public void OnLineLogin(CardInfo eCardInfo, OnOffLineInfo eOnOffLineInfo, BasicDataInfo eBasicDataInfo)
{
BLL.State.OnLineLogin s = new BLL.State.OnLineLogin();
s.OnLine(eCardInfo, eOnOffLineInfo, eBasicDataInfo);
}
U层:
//实例化上机外观层
OnLineFacade s = new OnLineFacade();
//定义卡实体
CardInfo eCardInfo = new CardInfo();
eCardInfo.CardNo = txtCardNo.Text.Trim();
//定义上机实体
OnOffLineInfo eOnOffLineInfo = new OnOffLineInfo();
eOnOffLineInfo.CardNo = txtCardNo.Text.Trim();
//定义基本数据实体
BasicDataInfo eBasicDataInfo = new BasicDataInfo();
//调用外观的方法
s.OnLineLogin(eCardInfo, eOnOffLineInfo, eBasicDataInfo);
总结:
现在发现自己之前学习设计模式的时候是走马观花,只是知道有这个模式,现在用到了才理解其中的结构图以及怎么根据结构图写代码,每一阶段有不同的理解,每天都在进步,↖(^ω^)↗!