界面逻辑和业务逻辑分离的重要性
2005-06-29 15:35
381 查看
我在最近的一个项目(WinForm)中遇到一个这样的问题,下面对问题陈述:
某工资计算模块的界面很复杂,8个DataGrid分别和8个DataSet绑定,还有一大堆的TextBox关联另外两个DataSet里面的数据。更新界面的某一地方的数据,其他数据源相应的地方会变化。不谈论对需求分析到设计的好坏,在这样一个复杂的UI下面,处理数据同步问题令我好担忧。在最近的测试过程中,发生莫名奇妙的错误,找不到错误源,简直郁闷至死!主要是在某些情况下,数据变得不同步了,根本经不起“猴子测试”(在界面上乱点),悲哀至此,下定决心把关键部分重写。
在重写过程中,我就发现了一个重要的问题:[b]控制界面的逻辑和处理业务数据的逻辑应各自独立,就算界面显示数据有错误,但实际的数据仍是平衡的。
[/b] 举例:在DataGrid中,一个CellValue从10 -》100,差值(新值和旧值相减)是90。我们要根据这个差值去处理其他数据的同步。
首先,问题是我们如何取出这个差值,开始我的做法是:DataGrid提供一个事件:ValidatingEditor。这个事件在输入的新值到写入数据源之前提供一个验证,在这里我们可以用EventArgs里面的新值和当前的值进行比较,得出差值。如果差值符合要求(业务逻辑),则把这个差值更新到各个相应数据源中去来保持数据同步。如果差值不符合要求,则提示错误信息,并还原原值。咋一看,什么问题也没有,逻辑也清晰,大家也觉得是吧?
在测试过程中,问题就出现了,往往是输入一个新值后,“其他数据源”也同步了,但是回头一看,旧值还是旧值,新值并没有填充到“本数据源”中去,why?找了很长时间,虽然我们最终找出问题出在控件本身上面,但是如何从根本上杜绝这类问题的发生呢?
就上面这个例子来说,我们找差值去同步数据的时候,在是写在ValidatingEditor这个事件上面的。如果在这个事件的处理过程中发生了一些我们异想不到的异常(可能是控件本身引发的或者是我们自己引发的),就会造成数据出错。所以进行了以下改造:
考虑到如果ValidatingEditor验证成功,必然会引发一个CellValueChanged事件,这里可以肯定数据源是被改变的了。所以,在ValidatingEditor只负责数据验证和提示错误信息,验证不成功CellValueChanged不会被引发,如果成功,在事件CellValueChanged得到差值去同步各个数据源。注意:取差值时,尽量不要获取控件提供的值(上面是从EventArgs去取的),而直接从数据源本身去取,这里就一定保证了数据的平衡性。我是这样得到差值的(DataSet某Row):
decimal v = (decimal)pdRow["PayMoney", DataRowVersion.Proposed] - (decimal)pdRow["PayMoney", DataRowVersion.Current];
这里就算控件本身发生问题而导致数据显示错误的话,但我们实际上的数据也是正确的(平衡)。只要在同步完毕之后,调用:
dataGridView.UpdateCurrentRow();
界面和数据源保持一致了。上面可能是特例,但是原则我认为应该这样做。希望对各位有启发。~ ^^
某工资计算模块的界面很复杂,8个DataGrid分别和8个DataSet绑定,还有一大堆的TextBox关联另外两个DataSet里面的数据。更新界面的某一地方的数据,其他数据源相应的地方会变化。不谈论对需求分析到设计的好坏,在这样一个复杂的UI下面,处理数据同步问题令我好担忧。在最近的测试过程中,发生莫名奇妙的错误,找不到错误源,简直郁闷至死!主要是在某些情况下,数据变得不同步了,根本经不起“猴子测试”(在界面上乱点),悲哀至此,下定决心把关键部分重写。
在重写过程中,我就发现了一个重要的问题:[b]控制界面的逻辑和处理业务数据的逻辑应各自独立,就算界面显示数据有错误,但实际的数据仍是平衡的。
[/b] 举例:在DataGrid中,一个CellValue从10 -》100,差值(新值和旧值相减)是90。我们要根据这个差值去处理其他数据的同步。
首先,问题是我们如何取出这个差值,开始我的做法是:DataGrid提供一个事件:ValidatingEditor。这个事件在输入的新值到写入数据源之前提供一个验证,在这里我们可以用EventArgs里面的新值和当前的值进行比较,得出差值。如果差值符合要求(业务逻辑),则把这个差值更新到各个相应数据源中去来保持数据同步。如果差值不符合要求,则提示错误信息,并还原原值。咋一看,什么问题也没有,逻辑也清晰,大家也觉得是吧?
在测试过程中,问题就出现了,往往是输入一个新值后,“其他数据源”也同步了,但是回头一看,旧值还是旧值,新值并没有填充到“本数据源”中去,why?找了很长时间,虽然我们最终找出问题出在控件本身上面,但是如何从根本上杜绝这类问题的发生呢?
就上面这个例子来说,我们找差值去同步数据的时候,在是写在ValidatingEditor这个事件上面的。如果在这个事件的处理过程中发生了一些我们异想不到的异常(可能是控件本身引发的或者是我们自己引发的),就会造成数据出错。所以进行了以下改造:
考虑到如果ValidatingEditor验证成功,必然会引发一个CellValueChanged事件,这里可以肯定数据源是被改变的了。所以,在ValidatingEditor只负责数据验证和提示错误信息,验证不成功CellValueChanged不会被引发,如果成功,在事件CellValueChanged得到差值去同步各个数据源。注意:取差值时,尽量不要获取控件提供的值(上面是从EventArgs去取的),而直接从数据源本身去取,这里就一定保证了数据的平衡性。我是这样得到差值的(DataSet某Row):
decimal v = (decimal)pdRow["PayMoney", DataRowVersion.Proposed] - (decimal)pdRow["PayMoney", DataRowVersion.Current];
这里就算控件本身发生问题而导致数据显示错误的话,但我们实际上的数据也是正确的(平衡)。只要在同步完毕之后,调用:
dataGridView.UpdateCurrentRow();
界面和数据源保持一致了。上面可能是特例,但是原则我认为应该这样做。希望对各位有启发。~ ^^
相关文章推荐
- 业务逻辑与界面元素分离的一次小尝试
- 界面层与业务逻辑分离
- MFC(0)关于MFC中的界面与业务逻辑的分离
- MVP:界面与业务逻辑分离在Winform中的应用
- QT之界面与业务逻辑的分离
- Delphi中实现界面与业务逻辑的分离
- 所思所想 关于asp.net界面业务分离
- PyQt5系列教程(六)如何让界面和逻辑分离
- Android新闻客户端开发2--主界面业务逻辑实现
- 工作中业务和功能逻辑分离
- MFC的 界面与逻辑分离(一)
- 用户界面与业务逻辑的分离
- 注册界面设计及实现之(二)注册业务逻辑的实现
- 界面和业务代码分离的记事本
- EF5 操作数据库,分离数据操作与业务逻辑
- 播放器实例,采用业务逻辑分离模式即mvc模式
- 结合模式分离GEF的业务逻辑和视图逻辑
- 错过方知我不知:数据库设计中主键唯一且与业务逻辑无关的重要性
- 第十五课、用户界面与业务逻辑的分离------------------狄泰软件学院
- 基于Android的小巫新闻客户端开发--主界面业务逻辑实现