叙事过程还是老样子-和大家说说自己关于实现某项功能的时候的思考过程,并非开门见山,直接体现核心要点;Reading Patiently.............
初步的话dang当然还是逻辑的考虑,这样的话,相应敲代码的时候才比较省事、省时;暂时没有按要求画UML图,所以还是以we文字的形式描述;
(1)根据上机时间文本框控件有无值,判断用户是否正在上机;
(2)是的话,将相应的文本框控件中信息更新到LineLog表中;
1.利用D层的查询语句将下机时间获取到消费时间;
2.通过消费时间开始计算消费金额;
3.余额等信息更新到LineLog表中;
如果这里不理解第一条为什么的话,可以期待下一篇“机房上下机设计”;那么利用D层通过下机时间获取消费时间该怎么搞定腻!我们一起来看看吧。
public List<LineLogInfo> GetList(string sid)
{
//获取当前时间
string sqlDate = "select GetDate()";
//字符串截取方法,获取
DateTime nowTime = Convert.ToDateTime(SqliteHelper.ExecuteScalar(sqlDate).ToString().Split(new char[] { '.' })[0]);
string sql = @"select * from lineLoginfo where sid=@sid and status='true'";
SqlParameter sp = new SqlParameter("@sid", sid);
DataTable dt = SqliteHelper.GetDateTable(sql, sp);
List<LineLogInfo> list = new List<LineLogInfo>();
foreach (DataRow row in dt.Rows)
{
LineLogInfo llInfo = new LineLogInfo();
llInfo.Sid = row["sid"].ToString();
llInfo.StudentName = row["studentName"].ToString();
llInfo.Sex = Convert.ToChar(row["sex"]);
llInfo.OnTime = Convert.ToDateTime(row["ontime"]);
llInfo.OffTime = nowTime;
if (row["ontime"] == DBNull.Value)
{
llInfo.OnTime = null;
}
else
{
llInfo.OnTime = Convert.ToDateTime(row["ontime"]);
}
list.Add(llInfo);
}
return list;
}
也正是因为这样操作的,这样才开始利用B层该有的功能-逻辑判断;也便开始计算“消费时间”。
public List<LineLogInfo> GetList(string sid)
{
List<LineLogInfo> list = illiiDal.GetList(sid);
if (list.Count!=0)
{
foreach (var item in list)
{
item.ConsumeTime = DateDiff(item.OffTime, Convert.ToDateTime(item.OnTime));
}
}
return list;
}
private string DateDiff(DateTime dateTime1,DateTime dateTime2)
{
string dateDiff = null;
TimeSpan ts1 = new TimeSpan(dateTime1.Ticks);
TimeSpan ts2 = new TimeSpan(dateTime2.Ticks);
TimeSpan ts = ts1.Subtract(ts2).Duration();
dateDiff = (ts.Days * 24 * 60+ts.Hours*60+ts.Minutes).ToString();
return dateDiff;
}
既然获取到了消费时间,那么现在岂不是要“计算金额”,只要这个搞定的话,我就可以更新表了,qibu岂不美哉;此时jiuk就开始看职责链模式,如果感觉不会应用的话,可以Try,大不了删除后接着删,慢慢就会习惯的;
- 职责链模式:封装了不同的方法,但是“流程化”判断参数中信息;
- 策略模式:封装不同的算法,但是在使用的时候需要进行“判断”,然后实例化;
- 不和简单工厂相结合的话,在用的时候直接实例化具体算法即可;
- 反之,即把直接实例化对象从主窗体推迟到维护类(Context)中实现,即解耦-类与类之间的分离;
- 当然如果感觉简单工厂可是没有什么意思,更不符合面向对象的sixi思想和原则,那么此时可以利用反射来优化;
---------------------------------------------------------------------------------------------------------------------------------------------------------
这里为了与标题相对应,所以仅仅描述职责链和外观模式;需要在B层中续写三个流程的“链”;
- 抽象链
public abstract class OperateMoneyManager
{
protected OperateMoneyManager successor;
protected LineLogInfoDal lliDal = new LineLogInfoDal();
public void SetSuccessor(OperateMoneyManager successor)
{
this.successor=successor;
}
public abstract decimal GetMoney(LineLogInfo line, BasicDataInfo basic, StudentTypeInfo studentType);
}
- 流程链----这里仅仅做个示范,具体的依照自己逻辑编写即可;
public class OperateMoneyOne : OperateMoneyManager
{
public override decimal GetMoney(LineLogInfo line, BasicDataInfo basic,StudentTypeInfo studentType)
{
if (Convert.ToInt32(line.ConsumeTime)<=Convert.ToInt32(basic.LeastTime))
{
line.ConsumeCash = Convert.ToDecimal(0);
}
else if(successor!=null)
{
successor.GetMoney(line, basic,studentType);
}
return line.ConsumeCash;
}
}
- 外观模式
public decimal Money(LineLogInfo line,BasicDataInfo basic,StudentTypeInfo studentType)
{
decimal consumeMoney = 0;
OperateMoneyManager mOneBll = new OperateMoneyOne();
OperateMoneyManager mTwoBll = new OperateMoneyTwo();
OperateMoneyManager mThreeBll = new OperateMoneyThree();
mOneBll.SetSuccessor(mTwoBll);
mTwoBll.SetSuccessor(mThreeBll);
return mOneBll.GetMoney(line, basic, studentType);
}
- U层-因为我直接通过传参数(LineLoginfo、BasicData、StudentTypeInfo)
//通过查询方法,在B层搞定消费时间,然后一起返回,最后利用职责链模式,算完后一块再更新
List<LineLogInfo> list = lliFacade.GetList(txtSid.Text.Trim());
//这里也没有必要遍历,以为仅仅存在一个返回值
//foreach (var loginfo in list)
//{
LineLogInfo llInfo = list[0];
BasicDataInfo bdInfo = bFacade.GetList();
//这里最好也给学生类型传值,重写GetList方法;
Dictionary<string, string> dic = new Dictionary<string, string>();
dic.Add("SType", txtType.Text);
List<StudentTypeInfo> listType = stiFacade.GetList(dic);
StudentTypeInfo sTinfo = listType[0];
#region 计算完消费的钱后,需要更新学生表中的金额
//查整个学生表,后进行实例化赋值
Dictionary<string, string> dicStudentInfo = new Dictionary<string, string>();
dicStudentInfo.Add("sid", txtSid.Text);
StudentInfo studentInfo = siFacade.GetList(dicStudentInfo)[0];
studentInfo.SCash = studentInfo.SCash - oFacade.Money(llInfo, bdInfo, sTinfo);
if (siFacade.Edit(studentInfo))
{
txtCash.Text = studentInfo.SCash.ToString();
MessageBox.Show("下机成功");
}
else
{
MessageBox.Show("下机失败");
}
想必到这里的话,指定有伙伴会看的比较蒙,我认为原因归咎于数据库表的设计;那么一块来看看吧。
综上所述,下机的功能到现在便是做完了,虽然路途挺坎坷的,但是实现的喜悦足以抵消之前的郁闷与怀疑;
后期博客会把《职责链与外观模式》+《策略模式》应用到上机过程中,博客会持续更新,敬请期待;
当然如果评论呼声比较高的话,机房主界面的设计也会分享给大家吆!