在我读到的所有(敏捷)文章中:保持代码和函数的小巧且易于测试。
我应该如何使用'控制器'或'协调员'课程?
在我的情况下,我必须导入数据。最后,我有一个协调这个的对象,我想知道是否有一种方法可以保持协调员精益(呃)和意味着(呃)。
我的协调员现在执行跟随(伪代码)
//Write to the log that the import has started
Log.StartImport()
//Get the data in Excel sheet format
result = new Downloader().GetExcelFile()
//Log this step
Log.LogStep(result )
//convert the data to intern objects
result = new Converter().Convertdata(result);
//Log this step
Log.LogStep(result )
//write the data
result = Repository.SaveData(result);
//Log this step
Log.LogStep(result )
Imho,这是“知道所有”课程中的一个,或者至少有一个是“不瘦和卑鄙”?
或者,我是否正在采取这种精益而且意味深远的事情,如果没有某种“肥胖”的进口商/协调员,是不可能对进口进行编程?
米歇尔
EDIT 这实际上是一个二合一的问题:一个是如何测试它,第二个是如果可以拥有一个'全部知道/粘合在一起'的协调员
答案 0 :(得分:11)
我相信很多人都不同意,但我认为你的方法总体来说足够精益。你在这里缺少的关键部分是依赖注入(也称为控制反转) - 所以不要在你的方法中新建Downloader,Converter等,你应该为这些类定义接口并在你的构造函数中“注入”它们类:
private Downloader downloader;
private Converter converter;
public MyClass(Downloader downloader, Converter converter)
{
this.downloader = downloader;
this.converter = converter;
//same with repository, it can't be a static class anymore
}
然后你只需在你的方法中使用这些实例:
//Write to the log that the import has started
Log.StartImport()
//Get the data in Excel sheet format
result = downloader.GetExcelFile()
//Log this step
Log.LogStep(result )
//convert the data to intern objects
result = converter.Convertdata(result);
//Log this step
Log.LogStep(result )
//write the data
result = repository.SaveData(result);
//Log this step
Log.LogStep(result )
现在执行此更改后,在测试中,您可以使用其中一个模拟框架(我使用RhinoMocks)将依赖项的模拟实现注入到您的类中。这样您就可以验证在转换器和下载器上调用了正确的方法,而无需从磁盘读取任何内容并解析任何电子表格。
如何使用RhinoMocks的示例在他们的文档中:http://ayende.com/wiki/Rhino+Mocks+Documentation.ashx
如果你遇到问题,请不要犹豫,提出另一个问题:)
答案 1 :(得分:3)
我有类似的问题,我解决它的方法是真正正确看待SRP(单一责任委托人)。
ExcelFileReader 谁可以读取excel文件并返回一组List(行)
解析器它的工作是使用分隔符解析从ExcelFileReader返回的行
导入程序,它处理从FileParser返回的DataSet导入正确的表。
这使其保持可测试形式,因为ExcelFileReader不依赖于Parser或Importer。这适用于Parser,只需将TextReader传递给它就可以测试。
这有帮助吗?
答案 2 :(得分:1)
有一个班级可以做我认为的 mediator pattern 。
我发现打击必须有合作者的课程(这就是你现在遇到的)的一种方法是做模拟单元测试。
你基本上嘲笑你的合作者并为这些合作者设定期望。
不幸的是你正在使用C#而我不知道C#的任何Mock库。 但是我相信谷歌可以帮你找到一个模拟库。
您可以只使用模拟库来实现或扩展协作者的类,并覆盖和实现您希望使用产生预期输出的方法调用的方法。
正如迈克尔所指出的那样,如果你的协作者有依赖注入接线,那就更容易了。
答案 3 :(得分:1)
您的评论和记录器(单身?)太吵了:
Log.StartImport();
result = new Downloader().GetExcelFile()
Log.Step(result);
result = new Converter().Convertdata(result);
Log.Step(result);
result = Repository.SaveData(result);
Log.Step(result);
由于你有三个必须一起发生的步骤,所以它们会在Converter
中完成。使用DI传递到Converter
Downloader
和Repository
。现在你最终得到:
Log.StartConvert();
convert.ExcelToRepository(); //passed in with DI
注意所有Log步骤结果都在相应的操作中完成。
答案 4 :(得分:0)
我发现这个article在决定我的代码是否真的精简并且意味着
时特别有用