C#界面设计,公开库类?

时间:2011-06-13 13:59:16

标签: c# oop architecture interface

我想定义一个接口“IFile”,其中包含一组键/值对“元数据”。获取或设置这些键/值对时,IFile实现者应该能够采取行动。最好的方法是什么?我看到三种方法:

方法1)获取/设置字典对象:

public interface IFile
{
    ...

    Dictionary<String, String> GetMetadata();

    void SetMetadata(Dictionary<String, String> metadata);
}

方法2)直接使用Dictionary类:

public interface IFile
{
    ...

    Dictionary Metadata();
}

并且在IFile的实现中,可以提供一个继承的Dictionary版本,它可以作用于get / set。

方法3)完全避免使用Dictionary并提供自定义界面,例如:

public interface IMetadata
{
    String GetValue(String key);        
    void SetValue(String key, String value);        
    Boolean Contains(String key);        
    void Delete(String key);  

    ...
}

public interface IFile
{
    ...

    IMetadata Metadata();
}

我倾向于方法3,因为它让实现者决定如何实际实现元数据数据结构。其他解决方案强制使用词典。然而,方法3似乎涉及许多额外的包装代码。

我觉得在这个问题的背后,在设计类层次结构时存在更深层次的困境,即是直接公开库类还是暴露一些隐藏内部使用的库类的包装函数。我在制作OOP设计方面没有什么实际经验,因此非常欢迎有关“正确方法”的建议!

谢谢,

拉​​斯

4 个答案:

答案 0 :(得分:1)

如果在编译时已知元数据的类型,那么我个人可能会这样做:

public interface IFile
{
    ...

    IDictionary<string, string> Metadata { get; }
}

注意 - IDictionary而不是Dictionary - 它将实现类留给了要使用的字典实现类型。

(我将字典类型的字符串用作示例,也因为这是您用于IMetadata的类型 - 必要时进行更改以满足您的需求)

ps - 如果元数据的键范围是固定的并且相对较小,那么将键设为枚举 - 这比字符串比较更有效。

答案 1 :(得分:1)

我喜欢选项3(定义界面中的方法),因为:

  1. 它不会强制执行 使用特定的数据结构。
  2. 它更可测试/可模拟。

答案 2 :(得分:1)

方法4:

public class JFile
{
    ...

    protected Dictionary Metadata() { ... }

    ...

    // --> all this use "Dictionary" internally
    // --> but, do somthing to other "IFile" fields

    public String GetValue(String key) { ... }
    public void SetValue(String key, String value)  { ... }
    public Boolean Contains(String key)  { ... }
    public void Delete(String key)  { ... }
}

对不起,如果它看起来我做了一个复杂的答案。

我打算建议方法2,但是......

...因为你提到当主要对象/界面“IFile”时,必须在元数据的单个值更改时执行某些操作,并且元数据项没有“委托“,”事件“,无论如何,以及仍然对元数据进行分组的好主意。

如果您的界面仅存储数据,而在添加或删除项目时不执行任何操作,方法2将更加实用。

在我看来,你自己很复杂,直接进入界面。我建议:

  1. 制作完整的演示工作班MyClass
  2. 使用所有相同的方法创建一个抽象超类,类MyClass:MySuperClass, 有一个工作演示。
  3. 获取抽象超类,并设计基于该超类的接口
  4. 有一种“更好的方式”,但“正确,完美,方式”并不存在于软件开发中,因为它过于复杂,只能用一种方式来做事。即使你选择另一种方法,如果它有效,那么它也可以。

    祝你好运; - )

答案 3 :(得分:0)

如果您关注的是在键值对字典中强制继承字典,为什么不使用IDictionary?

那么你的第一种方法是有效的。