在将代码附加到默认按钮单击事件时,我正在尝试遵循良好的编码标准。有两个选项:在Click事件处理程序中包含几行代码或包括最终与这些代码行相同的方法。
什么是软件设计原则,或者为什么我会使用这种或那种方式的具体原因?
[另外,它是一个现有的标准winforms应用程序,只是稍微扩展了一点。]
选项A:
private void btnExport_Click(object sender, EventArgs e)
{
var FileName = getFileName(reportPrefix);
if (fileName == null)
{
return;
}
SaveFile(fileName, QueryString);
}
选项B:
private void btnExport_Click(object sender, EventArgs e)
{
DoExport();
}
private void DoExport()
{
var FileName = getFileName(reportPrefix);
if (fileName == null)
{
return;
}
SaveFile(fileName, QueryString);
}
答案 0 :(得分:3)
我会建议选项B出于以下原因:
关注点分离:处理事件(EventHandler)或委托的代码是分离与执行实际工作的实际实现逻辑相同用另一种方法封装。
方法DoExport
的意图从名称中清晰可见。如果有人阅读您的代码,它将被解释为
选项B: “点击按钮时导出。”
选项A: “单击按钮时,如果fileName为,则读取文件名
空,然后返回,否则保存文件。“
哪种听起来更容易?出于可读性目的,选项B提供了一种清晰简洁的方式来表达您的意图。
如果您决定将button
更改为另一个控件,如anchor,linkButton,Label或任何其他控件,则无需将事件处理程序与实现详细信息绑定。与DoExport
方法一样,不应该依赖EventArgs' or the
发件人`对象。
将来,需要从代码中的其他位置调用导出功能(DoExport
)。然后,您可以轻松调用DoExport
方法。
测试:如果您将此方法设为公开,并且您想要测试它。测试方法要比编写代码来引发事件然后测试功能要容易得多。
答案 1 :(得分:2)
两者都没有,但B比A更接近:
SRP(单一责任原则)建议您将业务逻辑与UI分开,而不仅仅是在方法级别,而是至少一个级别(命名空间和/或库级别分离)也可能有用)。这是因为UI可能会独立于导出逻辑的变化而发生变化。
包含btnExport_Click
的UI类负责驱动用户界面,向用户显示数据并路由用户交互,例如点击返回业务逻辑。
完全是另一个类,最好是在抽象之后,接口是理想的(DIP,Dependency Inversion Principle),负责导出:
public class YouUIClass
{
IExporter exporter;
private void btnExport_Click(object sender, EventArgs e)
{
var fileName = GetFileName(reportPrefix);
if (fileName == null)
{
return;
}
exporter.DoExport(fileName);
}
}
public class Exporter : IExporter
{
public void DoExport(string fileName)
{
SaveFile(fileName, queryString);
}
}
(您可能需要将一些参数,例如filename
或queryString
从UI传递到导出器方法,因为我假设GetFileName
是UI)。
一个巨大的优势是您可以在不涉及UI的情况下测试驱动业务逻辑。然后手动测试只是检查UI是否正确地将事件转发到后续层。
当以这种方式解耦UI时,有一些模式可以遵循这种方法,而不是滚动自己的模式,如MVC,MVP& MVVM。