zoukankan      html  css  js  c++  java
  • 界面逻辑和业务逻辑分离的重要性

    我在最近的一个项目(WinForm)中遇到一个这样的问题,下面对问题陈述:
            某工资计算模块的界面很复杂,8个DataGrid分别和8个DataSet绑定,还有一大堆的TextBox关联另外两个DataSet里面的数据。更新界面的某一地方的数据,其他数据源相应的地方会变化。不谈论对需求分析到设计的好坏,在这样一个复杂的UI下面,处理数据同步问题令我好担忧。在最近的测试过程中,发生莫名奇妙的错误,找不到错误源,简直郁闷至死!主要是在某些情况下,数据变得不同步了,根本经不起“猴子测试”(在界面上乱点),悲哀至此,下定决心把关键部分重写。
            在重写过程中,我就发现了一个重要的问题:控制界面的逻辑和处理业务数据的逻辑应各自独立,就算界面显示数据有错误,但实际的数据仍是平衡的。
            举例:在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();

    界面和数据源保持一致了。上面可能是特例,但是原则我认为应该这样做。希望对各位有启发。~ ^^
  • 相关阅读:
    C#.NET.JSON库
    C# .NET 私钥 RSA2,SHA256,签名
    fiddler 捕捉不到代码发出去的HTTP请求
    双网卡共享上网
    json 反序列化成键值对
    C# .NET 杀进程
    docker in centos error
    深入理解磁盘文件系统之inode
    CentOS下安装高版本GCC
    Mac 使用 launchctl 定时运行程序(转载)
  • 原文地址:https://www.cnblogs.com/wj/p/183367.html
Copyright © 2011-2022 走看看