17

有没有人有任何关于将逻辑排除在我的 GUI 类之外的建议?我尝试使用良好的类设计并尽可能地保持分离,但我的 Form 类通常最终会混入比我想要的更多的非 UI 内容,并且它往往使维护变得非常痛苦。

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

非常感谢。

4

8 回答 8

16

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

于 2010-06-25T12:08:36.140 回答
9

这实际上只是练习和自律的问题。我的意思是,我们都做到了。而且我们都在错误的条件下不时地这样做(经理/客户大喊“现在”与“正确”完成某事等)。

在编写驱动 UI 的代码时我会做的一件事(更多的是在 Web 端,但同样适用)是问自己每个代码单元(单行、条件、循环等)是否该部分代码的数量取决于 UI 的存在。如果我正在写一个文本框,那是依赖于 UI 的,所以它就在那里。但是,如果我正在计算将进入该文本框的结果,那可能是业务逻辑。

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

于 2010-06-25T12:14:05.743 回答
5

您需要研究设计模式,例如:

网站常用的模型-视图-控制器(MVC) (ASP.NET) WPF 常用的
模型-视图-视图模型(MVVM)

通过保持其中之一,您应该能够将应用程序的各个部分分开。

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

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

于 2010-06-25T12:09:43.297 回答
5

3 层架构是您正在寻找的。

您构建 2 个可重用层:

  • 数据访问层 (DAL),仅包含从数据库读取/写入所需的代码
  • 使用 DAL 的业务逻辑层 (BLL),包含业务规则、验证,并提供一个外观供 UI 使用

然后在您的 UI 项目中引用可重用层并仅处理 UI 特定的内容。UI 项目只与 BLL 对话,与 DAL 没有直接连接:

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

如果您想支持多种数据库类型,您可以拥有多个使用可重用组件的 UI 层,以及多个可互换的 DAL。

于 2010-06-25T12:14:03.013 回答
2

了解如何编写可以数据绑定到表单的控制器类以及如何执行数据绑定。在 WinForms 中,这主要归结为控制器类上的 INotifyPropertyChanged 和 IDataErrorInfo 接口以及表单类上的 BindingSource 实例。

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

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

赫比

于 2010-06-25T12:53:20.963 回答
1

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

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

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

于 2010-06-25T12:16:53.990 回答
1

您应该查看以下模式:

MVC (Model-View-Controller) MVVM (Model-View-View-Model) - 主要用于 WPF 中,具有丰富的数据绑定支持。MVP (Model-View-Presenter) - 通常用于 WinForms 和 Web 应用程序(因为无状态视图)

查看这篇博文,它提供了一个示例,说明如何使用 MVP 为一个演示者同时支持 Web 和 WinForms 视图: http ://www.cerquit.com/blogs/post/MVP-Part-I-e28093-Building-从头开始.aspx

此外,这里还有一篇博文描述了使用 MVP 模式对业务逻辑进行单元测试: http://www.cerquit.com/blogs/post/Model-View-Presenter-Part-II---Unit-Testing。 aspx

于 2010-06-25T12:27:45.917 回答
1

总之,它被称为重构

将代码放入 UI 中只有几个原因:

  1. 与表单上的控件交互
  2. 验证虽然这可以放在业务逻辑层,但我通常在 UI 中添加一个辅助方法(更容易)

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

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

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

于 2010-06-25T13:18:12.213 回答