这是我的初始方法
public String GetAllDocuments(string url,int pager =0)
{
if (SessionInfo.IsAdmin)
{
ReportHandler dal = new ReportHandler();
var documents = dal.FetchDocumentsList(SessionInfo.ClientID, pager);
string documentsDataJSON = JsonConvert.SerializeObject(documents);
return documentsDataJSON;
}
else
{
return "Sorry!! You are not authorized to perform this action";
}
}
Visual Studio显示以下代码指标: -
成员:getallDocuments(String,int):字符串
可维护性指数:67
循环复杂性:2
类耦合:7
代码线:7
因此,为了改进它,我修改了下面的方法: -
public String GetAllDocuments(string url,int pager =0)
{
ReportHandler dal = new ReportHandler();
var documents = dal.FetchDocumentsList(SessionInfo.ClientID, pager);
//moved the JSON Conversion to Separate class
string documentsDataJSON = JsonHandler<T>.ConvertToJSON(documents);
return documentsDataJSON;
}
但仍然将代码指标显示为
成员:getallDocuments(String,int):字符串
可维护性指数:72
循环复杂性:1
类耦合:5
代码线:5
我不能提交,除非可维护性索引为90 。
我还能做什么来改善代码指标。
另外,我正在考虑创建单独的方法/类的小事,不是开销
您通常应该封装出工厂界面中对象的任何创建,然后将其传递给想要使用它的类的构造函数。
因此,您的班级将具有类似的构造函数和字段:
public MyClass(IReportHandlerFactory reportHandlerFactory)
{
if (reportHandlerFactory == null)
throw new ArgumentNullException(nameof(reportHandlerFactory));
_reportHandlerFactory = reportHandlerFactory;
}
private readonly IReportHandlerFactory _reportHandlerFactory;
这被称为依赖注入,特别是构造函数注入。
为了有效地执行此操作,您可能还希望为ReportHandler
类创建一个接口。然后,出厂接口将进行这样的操作:
public interface IReportHandlerFactory
{
IReportHandler Create();
}
和您的报告处理程序接口:
public interface IReportHandler
{
IEnumerable<Document> FetchDocumentsList(Guid clientID, int pager);
}
...等等。希望您能得到这个主意。
您还应该将您的方法分开,也许是这样:
public String GetAllDocuments(string url,int pager =0)
{
if (SessionInfo.IsAdmin)
{
return documentsData(_reportHandlerFactory, SessionInfo.ClientID, page);
}
else
{
return "Sorry!! You are not authorized to perform this action";
}
}
private static String documentsData(
IReportHandlerFactory reportHandlerFactory,
Guid clientID,
int pager)
{
IReportHandler dal = reportHandlerFactory.Create();
var documents = dal.FetchDocumentsList(clientID, pager);
string documentsDataJSON = JsonConvert.SerializeObject(documents);
return documentsDataJSON;
}
注意:说实话,这个问题确实更适合https://codereview.stackexchange.com/
我强烈推荐以下有关此主题的书:
干净的代码:敏捷软件工艺手册(Robert C. Martin)
和
.net中的依赖注入(Mark Seemann)
或Mark Seemann的博客。
以维护性索引作为工具,而不是目标。
,如果您没有意识到为什么您的代码首先不可维护,那么增加可维护性索引是没有意义的。您只会继续移动代码以满足索引,而无需了解您在做什么。
您的问题不应该是
如何更新此类/方法以改进代码指标?
但是
如何提高此类的可维护性?
我现在看到很多问题:
-
依赖性是隐式的,即您直接在方法内部进行
new
'。这使得代码不那么灵活,组合和可读。将reporthandler依赖性传递给
GetAllDocuments()
或类构造函数会更好。 -
它的测试不佳。如果reporthandler是接口(或抽象类),则可以在
GetAllDocuments()
测试中用假报告处理程序将其代替,以改善性能和测试。请注意,您不必使用工厂来做到这一点,一个具有一个真实实现和测试实现的简单接口就足够好了。 -
参数
url
不使用。 -
SessionInfo.IsAdmin
是一种魔术速记,容易出现与上述问题相同的问题。如果您在控制器中,这没什么大不了的,但是如果您应该在业务层中,这将妨碍可检验性和可维护性。
如果您有兴趣使可维护性索引更好地阅读如何计算:http://www.projectcodemeter.com/cost_estimation/help/gl_maintainability.htm
您可以看到它主要取决于代码线的数量。
如果需要良好的设计,请停止使用具体实现,使用一个可靠的原理之一 - 依赖性反演。例如,而不是使用:
ReportHandler dal = new ReportHandler();
您使用以下内容:
IReportHandler dal = reportHandlerFactory.GetReportHandler();
// where reportHandlerFactory is IReportHandlerFactory which is also
// make dependency on interface but not on concrete class
甚至更好的是使用DI容器注入此类内容。