2010-06-25 455 views
9

有没有人对我的GUI类保持逻辑没有任何建议?我尝试使用良好的类设计并保持尽可能多的分离,但是我的Form类通常会以比我想要的更多的非UI内容混合在一起,而且这往往会使维护变得非常痛苦。在C#中分离用户界面和逻辑

(Visual Studio 2008 Professional,C#,Windows应用程序)。

非常感谢。

回答

6

把你的逻辑放在一个单独的程序集中;并且在不引用任何GUI软件包的情况下构建该程序集(例如System.Drawing,System.Windows.Forms等)。

+0

谢谢 - 我认为这是一个很好的实际起点,可以帮助我以正确的方式思考。 – Andy 2010-06-26 19:17:19

3

你需要寻找到设计模式,如:

Model-View-Controller(MVC)经常使用的网站(ASP.NET)
Model-View-View Model(MVVM)经常使用WPF

通过保持到一个这些你应该能够把应用程序的各个部分分开。

还有其他模式可以完成类似的工作。

此外,使用WPF进行开发可以提供帮助,因为UI由XAML定义,并且工作的代码是C#。这可以提供基本的分离度。如果您发现自己编写的只是操纵UI的C#代码,则可以退后一步并考虑“我应该在XAML中执行此操作吗?”。很显然,在后面的代码中你可能需要做的事情,但这是一个开始。

1

3层架构就是您要找的。

你建造2个可重复使用的层:从数据库

  • 业务逻辑层(BLL),这 消耗

    • 数据访问层(DAL),这 包含只需要 读码/写DAL,包含业务 规则,验证,并提供了一个 门面的UI使用

    然后在你的UI项目您引用可重用的图层并仅处理UI特定的内容。该UI项目谈判只对BLL,没有直接连接到DAL:

    UI < ---> BLL < ---> DAL

    你可以有多个消费层的用户界面您可重用的组件以及多个可互换的DAL(如果您要支持多种数据库类型)。

  • 4

    这实在只是一个练习和自律的问题。我的意思是,我们都做到了。而且我们都会在不合适的条件下不断地做到这一点(经理/客户大吼大叫“现在就完成”与“正确”等)。

    我在编写代码驱动UI时所做的一件事(在网页上更多,但同样的事情适用)是用代码的每个单元(单行,条件,循环等)问自己。)这段代码是否依赖于UI的存在。如果我正在写一个文本框,这取决于用户界面,所以它会去那里。但是如果我计算将在该文本框中出现的结果,那可能是业务逻辑。

    另一种方法(正如ChrisW在我输入时暗示的那样)是在非UI类库中首先开发逻辑。把尽可能多的逻辑放在那里(尽管你的判断是用来定义“逻辑”的,但不依赖于基于UI的库)。然后构建UI以利用该逻辑。有两种不同的方法来允许这两部分的并发开发,比如将接口类后面的逻辑程序集桩掉,并将UI部分编码到那些接口(然后使用依赖注入将程序集类插入接口)等等。

    0

    通常在这种情况下;我创建了一个辅助方法类,完成所有繁重的工作。

    至于保持逻辑分离;确定什么是关键组件,并将这些重构到辅助方法类中。例如;如果我正在处理一个GridView来根据它们是否被选中来更新记录;如果是,则在表单中更新ShipDate;如果该行被选中,我会先弄清楚;然后提取Id字段,然后提取ShipDate,然后将Id和ShipDate传递给我的帮助器类中的一个方法,该方法完成所有工作。

    单元测试可以成为你的朋友,基本上,如果你有任何“逻辑”类型的东西的代码;它应该有一个单元测试。如果它在GUI类中;很难测试;然而,一旦你重构它,单元测试应该是微不足道的。

    0

    你应该看看下面的模式:

    MVC(模型 - 视图 - 控制器) MVVM(模型 - 视图 - 视图模型) - 大多在使用WPF与它的丰富的数据绑定支持。 MVP(Model-View-Presenter) - 常用于WinForms和web应用(因为无状态视图)

    查看本博客文章,其中给出了如何使用MVP为Web和WinForms视图提供支持的示例一个主持人: http://www.cerquit.com/blogs/post/MVP-Part-I-e28093-Building-it-from-Scratch.aspx

    此外,进一步此处的博客文章介绍使用单元测试你的业务逻辑MVP模式: http://www.cerquit.com/blogs/post/Model-View-Presenter-Part-II---Unit-Testing.aspx

    1

    学习如何编写能够数据绑定到表单控件类和如何执行数据绑定。 在WinForms中,主要涉及控制器类上的INotifyPropertyChanged和IDataErrorInfo接口,以及表单类上的BindingSource实例。

    然后,您可以编写一个控制器类,其中包含UI的所有数据和逻辑,并且UI类简单地绑定到它。您的UI类变得非常简单,并且您的UI逻辑(保存在控制器中)变得非常易于测试(在针对UI类运行时,单元测试非常棘手,但在针对控制器类运行时更容易)。

    这是所有MVC/MVVM设计的基础。

    金龟

    1

    总之,它被称为重构

    只有几个原因,把代码放到UI:

    与窗体上的控件
    1. 互动
    2. 验证,尽管这可能是 放在业务逻辑层,但 我通常在 用户界面中添加辅助方法(更容易)

    所有其他“业务逻辑”代码都会进入另一个称为业务逻辑类的类。所有的数据库交互代码进入一个不同的类,称为数据访问类。

    当您在UI中编写代码时,只需问自己代码是否与窗体上的控件进行交互。如果不是,它可能属于另外两类。

    查看Martin Fowler关于“重构:改进现有代码设计”等重构的书籍。另一个流行词是关注点分离。我知道你可以在一个类中完成所有这些工作,但是如上所述,当它被分为类时,代码变得更加可读并且更易于调试。