有关如何清理此API的建议

时间:2010-09-24 18:03:41

标签: c# design-patterns api oop

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

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

我无法找到为所有解码设置1 Decode方法的方法,以便尽可能保持编码/解码的API尽可能干净(2种公共方法,tops,暂时)。

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

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

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));

其中,在两种情况下,进程(...)可能会在客户端使用4种类型的解码值重载函数。

4 个答案:

答案 0 :(得分:3)

你可以让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

答案 1 :(得分:1)

如果您正在编写图书馆/框架......这将是您努力工作中最宝贵的资源:-)我有硬拷贝并阅读封面以涵盖:
来自Microsoft的Design Guidelines for Developing Class Libraries

答案 2 :(得分:0)

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

答案 3 :(得分:0)

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