首页 > 解决方案 > 这种技术有名称吗?它是代码味道吗?

问题描述

我以前见过类似下面的代码,它导致一种“扩展访问方法”被添加到对象中。The extension method will appear in intellisense as only one method, but when selected, intellisense will appear with all the methods defined in the "manager" class. 这似乎是组织一组类似功能并整理主要对象的主要智能感知的好方法。

所以,我想知道这种技术是否有某种常用名称,以及它是否被认为是代码异味(除了主要对象承担太多责任和变得太大的一般问题)。

public class StringManager
{
    public StringManager(String value)
    {
        Value = value;
    }

    private String Value { get; set; }

    public int GetTwiceLength()
    {
         return Value.Length * 2;
    }

    public decimal GetHalfLength()
    {
         return Value.Length / 2;
    }
}

public static class StringExtensions
{
    public static StringManager Operations(this String value)
    {
        return new StringManager(value);
    }
}

上面的代码将像这样使用:

var myString = "the string";
var twiceLength= myString.Operations().GetTwiceLength();

为愚蠢的功能道歉。这是从 SO 上的一个示例中借用的,在该示例中实际推荐了该技术,并对其进行了修改以保护可能有罪的人。

标签: c#extension-methods

解决方案


这看起来像适配器模式

适配器是一种结构设计模式,它允许具有不兼容接口的对象进行协作。– [ https://refactoring.guru/design-patterns/adapter ]

让我解释一下为什么我认为这适用于这里:

C# 中的扩展方法只是带有一点语法糖的常规静态方法。函数的第一个参数的this关键字允许您调用它,就好像它是该类型的实例方法一样。但是你也可以像普通的静态方法一样调用它:

StringExtensions.Operations("your string").CallMethtod();

查看Operations实现:

public static StringManager Operations(this String value)
{
    return new StringManager(value);
}

我们可以看到这是一个普通的旧静态工厂方法,它返回 Manager 类的实例(= 适配器)。这相当于直接创建 apapter 实例(但实际上是有利的,因为它隐藏了“如何”创建新实例。例如,您可以合并并重用现有实例):

new StringManager("your string").CallMethod();

您的 Manager 类调整string类型/接口以与不同的接口兼容,提供所有“管理方法”而不是原始字符串方法。为了使“适配器”显式可见,使用中间变量(出于演示目的)会有所帮助:

var originalString = "你的字符串"; var adaptString = new StringManager(originalString); 适配String.CallMethod();

是代码味道吗?我不这么认为,不一定。您只是将一个类的接口调整为不同的接口(字符串接口到 StringManager 接口)。有人可能会争辩说,“Manager”不应该用在类名中,因为它不会添加任何有用的上下文并且基本上可以表示任何含义。迟早你的所有类都会成为某种 Manager 或 Service 或 ManagerService。

至于所有模式:在有意义并提供好处时使用它们。不要过度使用它们:不要仅仅为了使用模式而使用设计模式。有时最好不使用模式,即使存在模式或故意引入异味(使用代码注释来解释为什么以这种方式实现某些东西)。使用明智的判断。


推荐阅读