在C#中分离UI和逻辑

时间:2010-06-25 12:05:06

标签: c# user-interface business-logic code-separation

有没有人有任何关于保持逻辑不在GUI类中的建议?我尝试使用良好的类设计并保持尽可能多的分离,但我的Form类通常最终会混入比我想要的更多的非UI内容,并且它往往会使维护成为一种真正的痛苦。

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

非常感谢。

8 个答案:

答案 0 :(得分:12)

将您的逻辑放在一个单独的程序集中;并构建该程序集而不引用任何GUI包(例如System.DrawingSystem.Windows.Forms等)。

答案 1 :(得分:6)

这只是一个练习和自律的问题。我的意思是,我们都做到了。我们都会在错误的条件下不时地继续这样做(经理/客户大喊大叫“现在”和“正确”等等)。

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

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

答案 2 :(得分:4)

您需要研究以下设计模式:

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

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

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

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

答案 3 :(得分:3)

您正在寻找3层架构。

您构建了2个可重复使用的层:

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

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

  

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

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

答案 4 :(得分:1)

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

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

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

赫比

答案 5 :(得分:1)

总之,它被称为重构

将代码放入用户界面只有几个原因:

  1. 与表单上的控件交互
  2. 验证虽然可以 放在业务逻辑层但是 我通常在中添加一个辅助方法 用户界面(更容易)
  3. 所有其他“业务逻辑”代码都进入另一个称为业务逻辑类的类。所有数据库交互代码都进入一个称为数据访问类的不同类。

    当您在UI中编写代码时,只需询问自己代码是否与表单上的控件进行交互。如果没有,它可能属于其他两个类。

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

答案 6 :(得分:0)

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

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

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

答案 7 :(得分: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