我想定义一个接口“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设计方面没有什么实际经验,因此非常欢迎有关“正确方法”的建议!
谢谢,
拉斯
答案 0 :(得分:1)
如果在编译时已知元数据的类型,那么我个人可能会这样做:
public interface IFile
{
...
IDictionary<string, string> Metadata { get; }
}
注意 - IDictionary而不是Dictionary - 它将实现类留给了要使用的字典实现类型。
(我将字典类型的字符串用作示例,也因为这是您用于IMetadata的类型 - 必要时进行更改以满足您的需求)
ps - 如果元数据的键范围是固定的并且相对较小,那么将键设为枚举 - 这比字符串比较更有效。
答案 1 :(得分:1)
我喜欢选项3(定义界面中的方法),因为:
答案 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将更加实用。
在我看来,你自己很复杂,直接进入界面。我建议:
有一种“更好的方式”,但“正确,完美,方式”并不存在于软件开发中,因为它过于复杂,只能用一种方式来做事。即使你选择另一种方法,如果它有效,那么它也可以。
祝你好运; - )
答案 3 :(得分:0)
如果您关注的是在键值对字典中强制继承字典,为什么不使用IDictionary?
那么你的第一种方法是有效的。