【问题标题】:Suggestions for how to clean up this API有关如何清理此 API 的建议
【发布时间】:2010-09-24 18:03:41
【问题描述】:

对于一个有趣的项目,我正在尝试实施 BitTorrent 规范,现在我正在研究它的 BEncoding 部分。

编码基本上可以从int/string/dictionary -> string进行编码进行传输。我已经编写/测试了所有不同的编码/作为重载的 Encode(...) 方法工作,并且我已经编写/测试了/作为 DecodeString(...)、DecodeInt(...) 工作的各个解码方法) 等。

我想不出一种方法让所有解码都使用 1 种解码方法,以使编码/解码的 API 尽可能干净(暂时是 2 种公共方法)。

请注意,我有一个方法可以获取解码后的字符串将具有的结果类型。

客户端代码,现在每次他们想要解码消息时都必须看起来像这样:

string s = ...; // Encoded string
Type t = Encoder.GetDecodedType(s);
if (t == typeof(int))
    process(Encoder.DecodeInt(s));
else if (t == typeof(string))
    process(Encoder.DecodeString(s));
else if (t == typeof(Dictionary<string, string>))
    process(Encoder.DecodeStringDictionary(s));
else if (t == typeof(Dictionary<string, int>))
    process(Encoder.DecodeIntDictionary(s)):

我希望能够将其清理得更像:

string s = ...; // Encoded string
process(Encoder.Decode(s));

在这两种情况下,process(...) 都可能是客户端的重载函数,采用 4 种类型的解码值。

【问题讨论】:

    标签: c# design-patterns api oop


    【解决方案1】:

    您可以让 DLR 为您执行此操作。

    public static void Process(int i) { ... }
    public static void Process(string s) { ... }
    public static void Process(Dictionary<string, string> dic) { ... }
    public static void Process(Dictionary<string, int> dic) { ... }
    
    [...]
    
    public dynamic Decode(string input)     // or 'object' if you prefer
    {
        var t = GetDecodedType(input);
        if (t == typeof(int))
            return DecodeInt(input);
        else if (t == ...)
            // ...
    }
    
    [...]
    
    string s = ...; // Encoded string
    Process(Encoder.Decode(s));            // if you used 'dynamic' above
    Process((dynamic)Encoder.Decode(s));   // if you used 'object' above
    

    【讨论】:

    • 哦。这看起来很性感。我会查一下,但是是否有框架版本依赖才能使用动态?
    • @SnOrfus:恐怕它确实需要 .NET 4.0 或更高版本,是的。
    • 没关系,我最初是在 3.5 中工作的,但我没有绑定到特定版本。
    • 工作如梦。谢谢@Timwi
    【解决方案2】:

    如果您正在编写库/框架...这将是您努力中最宝贵的资源 :-) 我有硬拷贝并从头到尾阅读:
    Design Guidelines for Developing Class Libraries 来自 Microsoft

    【讨论】:

    • +1:这是一个很好的资源,我不知道。我今晚肯定会吃掉它。谢谢乔尔。
    【解决方案3】:

    我会说你应该遵循 Liskov 替换原则here 并为每种数据类型创建一个方法。这样,当您开始传递自定义对象时,您就不会继续增加使用 typeof 的痛苦。再次阅读您的问题后,您已经知道传递给它的类型,因此进一步支持删除 typeof 操作的需要

    【讨论】:

      【解决方案4】:

      我很困惑。为什么不简单地在公共 Decode 方法中执行 GetDecodedType 逻辑并确定类型,然后在确定后进行不同的调用?

      【讨论】:

      • 因为我不知道在设计时会调用 GetDecodedType 的 Decode 方法的返回类型。
      • 这是通过 WS 吗?动态链接库?客户端如何执行这些方法?如果是通过 WS,则必须定义返回类型,除非您要创建一个封装多种类型的自定义类型(以不同的方式冗余),否则似乎每种类型都有多个方法是要走的路...根据 Woot4Moo
      • 它是一个 DLL,客户端代码大部分是我的,但它最终(一旦可用)最终会成为一个开源项目,所以我希望有一个干净的 API尽可能。如果@Timwi 发布的内容不起作用,那么我可能不得不使用我已经拥有的内容(多种方法)。
      猜你喜欢
      • 1970-01-01
      • 2011-09-06
      • 2017-08-09
      • 2013-11-16
      • 1970-01-01
      • 2022-01-09
      • 1970-01-01
      • 2017-06-18
      • 1970-01-01
      相关资源
      最近更新 更多