鹅思晗小组三个菜鸟成就一个系统,在这个过程中我有幸负责BLL层和外观层的实现。做过机房的朋友都知道,BLL层一个亮点就是设计模式。
至今犹记去年六月份鹅思晗小组成立后,那几天轰轰烈烈的探讨,最终将功能进行了确定于此同时将B层用到的设计模式也进行了确定。经过去年软考的洗礼,又对设计模式学习一遍,这次再次捡起机房用设计模式时觉得比当初理解要深许多。
今天小编就和大家一起分享下如何利用备忘录模式来实现取消修改基本数据。
俗话说世上没有后悔药!!!于是:曾经,有一份真挚的爱情摆在我面前——馒头版诞生了。
·曾经有一个馒头丢在地上我没有去捡,
·等到我饿得走不动时我才追悔莫及。
·如果再有个馒头丢在我面前的话,
·我一定去捡,
·如果非要问我要在这个馒头里面加点什么的话,
·我希望是——钱!!!
在品完一笑之余,不得不感叹人生有太多的后悔之时,同时也再次体味到计算机带给我们的神奇世界!大家熟知的Ctrl+Z就很好体现这点。接下来就看一下我们机房收费系统中如何做到后悔药的功效。
·需求分析:
在机房收费系统中以管理员身份登录后有一功能——基本数据设定,它用来设定系统基本数据,主要是为计算收费时提供标准(见下图示一)。当使用者点击修改,改了点感觉不合理又不想改了,恢复原来的数据怎么办那?于是设定了取消修改来解决这个问题。
示意图一:功能展示图
图示一:功能展示
·实现想法:
解决方案一:犹记机房个人重构时,自己实现思路:当用户点击修改时,在界面上修改点数据,用户不想改,点击取消修改,执行从数据库中再查一遍把数据给重新显示到界面上。
示意图二:数据库中读数据实现取消修改
图示二:数据库中读数据实现取消修改
解决方案二:历经一年后,再次机房合作分析取消修改时,发现之前有两个缺点:
①功能方面:图示二中进行第二步时如果我点击确认后我还想回到我加载界面时默认的数据怎么办???
②性能方面:从数据库中读消耗资源。
忽然想到了备忘录模式不正好来解决这个问题吗?基本思想如下,在BLL层中添加一个存储类,来将数据暂存到这个类中!解决缺点①:当点击确认后再点取消修改是从此类中加载数据,这样就还原到窗体加载时数据。解决缺点②:点击取消修改是从B层读出数据,没必要再从数据库中加载数据。
示意图三:采用备忘录模式时点击取消修改
图示三:采用备忘录模式时点击取消修改
示意图四:采用备忘录模式时点击确认后再点击取消修改
图示四:采用备忘录模式时点击确认后再点击取消修改
上面有了这么诱人的后悔药,嘴馋的我不尝一下怎对得起那首经典的馒头版的曾经,有一份真挚的爱情摆在我面前的段子那?
实现
示例图五:类图
图示五:类图
代码展示:
·U层中基本数据窗体部分代码展示:
#region 加载窗体,加载所需信息
/// <summary>
/// 加载窗体,加载所需信息
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void frmBasicData_Load(object sender, EventArgs e)
{
txtIncreaseTime.Enabled = false;
BasicDataEntity bde = new BasicDataEntity();
List<BasicDataEntity> rs;
bde.UseState = "使用";
rs = bb.selectBasicData(bde);
txtIncreaseTime.Text = rs[0].IncreaseTime.ToString();
txtLeastMoney.Text = rs[0].leastMoney.ToString();
txtLeastTime.Text = rs[0].LeastTime.ToString();
txtReadyTime.Text = rs[0].ReadyTime.ToString();
txtRegular.Text = rs[0].Regular.ToString();
txtTemporary.Text = rs[0].Temporary.ToString();
//保存基本数据
caretaker.Memento = bb.SaveState(rs[0]);
}
#endregion
#region 单击事件,取消修改
/// <summary>
/// 取消修改
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnCancel_Click(object sender, EventArgs e)
{
//恢复基本数据
bb.RecoveryState(caretaker.Memento);
BasicDataEntity bbe = bb.displaybasicdata();
txtIncreaseTime.Text = bbe.IncreaseTime.ToString();
txtLeastMoney.Text = bbe.leastMoney.ToString();
txtLeastTime.Text = bbe.LeastTime.ToString();
txtReadyTime.Text = bbe.ReadyTime.ToString();
txtRegular.Text = bbe.Regular.ToString();
txtTemporary.Text = bbe.Temporary.ToString();
//调用确认事件
btnOk_Click(sender,e);
}
#endregion
·B层中BasicBLL代码展示:
#region 保存基本数据 RoleStateMementoBLL SaveState(BasicDataEntity basicda)
/// <summary>
/// 保存基本数据
/// </summary>
/// <param name="basicda"></param>
/// <returns></returns>
public RoleStateMementoBLL SaveState(BasicDataEntity basicda)
{
return (new RoleStateMementoBLL(basicda));
}
#endregion
#region 恢复基本数据 RecoveryState(RoleStateMementoBLL memento)
/// <summary>
/// 恢复基本数据
/// </summary>
/// <param name="memento"></param>
public void RecoveryState(RoleStateMementoBLL memento)
{
this.basicentity = memento.baicentity;
}
#endregion
·B层中BasicCaretaker代码展示
public class BasicCaretaker {
public int BasicMemento;
public BasicDataMemento m_BasicDataMemento;
#region 恢复数据 void GetMemento(BasicDataMemento Data)
/// <summary>
/// 恢复数据
/// </summary>
/// <param name="Data">原有数据</param>
public void GetMemento(BasicDataMemento Data){
IDAL.IBasicData IGetMen;
Factory.DBfactory factory = new Factory.DBfactory();
IGetMen = factory.CreateIBasicData();
}
#endregion
}
凡事有利必有弊!虽然采用备忘录模式增加了程序的复杂度(比如:本来可以直接操作B层的状态存储类【本例:BasicDataMemento】就可以,在备忘录模式中加了个管理类【BasicCaretaker】来间接操作)但是它增加程序灵活性,可扩展性,本次应用只是恢复到固定一个时刻数据,其实它可以利用管理者类来实现恢复多个时刻的数据。
另外BLL层职责是处理业务逻辑,利用备忘录模式后却在B层多出一个数据存储类,在一定程度上不符合分层解耦的思想。
世上没有完美无缺的事情,权衡好其利弊即可。