【问题标题】:How to update this class/method to improve Code Metrics如何更新此类/方法以改进代码度量
【发布时间】:2017-05-05 08:53:59
【问题描述】:

这是我的初始方法

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) : string
可维护性指数: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) : string
可维护性指数:72
圈复杂度:1
类耦合:5
代码行数:5

我不能提交这个,除非可维护性指数是 90+。

我还能做些什么来改进代码指标。

另外,我正在考虑为这么小的事情创建单独的方法/类不是开销

【问题讨论】:

  • 你考虑过使用 DI 还是 IoC?
  • 这个问题太宽泛了。该解决方案通常基于对类设计的重大重构以减少类耦合。无论如何,你应该看看依赖注入。
  • 代码指标?让我休息一下……

标签: c# asp.net performance visual-studio code-metrics


【解决方案1】:

您应该经常将任何对象创建封装在工厂接口中,您将其实例传递给想要使用它的类的构造函数。

因此,您的类将具有如下构造函数和字段:

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 的博客。

【讨论】:

  • 哇。对我很有见地。真的很感激:)
  • Mattherw,我在你的帖子中一切都很清楚。但我不确定我应该如何实现接口IReportHandlerFactory
  • 请将其添加到您的帖子中。它将引导我走很长一段路:)
  • “你应该经常将任何对象的创建封装在工厂接口中”:我不同意经常任何创建。比没有工厂好的具体案例很少。
【解决方案2】:

将可维护性索引作为工具,而不是目标。

如果您一开始就没有意识到为什么您的代码不可维护,那么增加可维护性指数就毫无意义。您将只是不断移动代码以满足索引,而不了解您在做什么。

你的问题不应该是

如何更新此类/方法以改进 Code Metrics?

但是

如何提高这个类的可维护性?

我现在发现它有很多问题:

  • 依赖是隐式的,即你new'ing 直接在方法内部。这会降低代码的灵活性、可组合性和可读性。

    将 ReportHandler 依赖项传递给 GetAllDocuments() 或类构造函数会更好。

  • 它的可测试性很差。如果 ReportHandler 是一个接口(或抽象类),您可以在 GetAllDocuments() 的测试中用伪造的报告处理程序替换它,以提高性能和测试。请注意,您不必使用工厂来执行此操作,具有一个实际实现和一个测试实现的简单接口就足够了。

  • 未使用参数url

  • SessionInfo.IsAdmin 是一种魔术速记,容易出现与上述相同范围的问题。如果您在控制器中,这没什么大不了的,但如果您应该在业务层中,这将妨碍可测试性和可维护性。

【讨论】:

  • 非常感谢您分享您的意见。
  • 能否请您查看我更新的 sn-p codereview.stackexchange.com/questions/150382/…
  • 如果可以分享您的评论,或者如果使用 sn-p 可以展示我如何使用 SOLID 原则实现相同功能,我将非常感谢您
【解决方案3】:

如果您对提高可维护性指数感兴趣,请阅读它是如何计算的:http://www.projectcodemeter.com/cost_estimation/help/GL_maintainability.htm

您可以看到它主要取决于代码行数。

如果想要好的设计,停止使用具体的实现,使用 SOLID 原则之一 - 依赖倒置。例如,不要使用:

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 容器注入这些东西。

【讨论】:

  • 你的帖子对我来说似乎很有吸引力。您能否在您的帖子中添加更多关于IReportHandler dal = reportHandlerFactory.GetReportHandler(); 的详细信息。
  • @Kgn-web,我编辑了我的答案。这对你有意义吗?无论如何,这只是一个示例,您应该根据良好编程的原则(模式、SOLID 等)来设计代码。正如这里的其他推荐一样,值得从 DI 开始
  • 是的。对于我,这说得通。谢谢:)
  • 请查看这篇文章。 stackoverflow.com/questions/41240184/…
  • 为什么是工厂?另外,你没有解释为什么这是好的设计。
猜你喜欢
  • 1970-01-01
  • 2011-04-13
  • 1970-01-01
  • 2023-03-20
  • 2016-12-20
  • 1970-01-01
  • 1970-01-01
  • 2013-03-15
  • 2015-09-16
相关资源
最近更新 更多