订单敏感呼叫的设计模式

时间:2010-02-21 17:08:13

标签: c# .net design-patterns

我正在设计一个小目录同步引擎,它可以使用不同类型的源并处理增量同步。我已经为DirectorySource定义了一个接口,目前看起来像这样:

public interface IDirectorySource
{
    IEnumerable<IDirectoryEntry> GetChanges(IList<string> attributes, IChangeToken token);
}

我确实想提供一个枚举器而不是列表,以便能够避免不必要的内存分配,但我的问题是我还想返回一个新的IChangeToken,其中包含下次调用所需的新状态信息GetChanges(进行增量更新)。在完成枚举之后,必须先计算的changetoken,因为其他人可能会在不同的调用之间更新目录。

我已经考虑过第二个接收新令牌的IChangeToken参数,但这感觉不太好(并且不会保持一致,因为令牌会立即返回,但在枚举完成之前无法填充)..我已经考虑过返回包含GetEnumerator方法和GetToken方法的“IChangeSet”接口之类的东西,但问题仍然是对枚举器方法的后续调用返回不同的数据(因此具有不同的changetokens) )。

如何设计一个界面,使我的界面用户“不可能”在我的GetChanges枚举器和检索相关的ChangeToken时使用它是错误的?

我希望我的问题有道理......;)..我很难弄清楚我的问题使用什么标题......;)

2 个答案:

答案 0 :(得分:1)

在函数式编程语言中,有一个名为Tuple的结构。在这里我相信Tuple是最好的选择 - 每个设计的元组意味着它的项目之间没有关系。当前版本的.NET Framework(3.5)不支持元组,但下一个(4.0)支持元组。如果有必要,你总是可以自己实现元组 - 没什么大不了的。不幸的是,C#缺少对元组的语言支持,但是F#例如。

所以,总结一下,让你的界面像这样:

Tuple<IEnumerable<IDirectoryEntry>, IChangeToken> GetChanges(IList<string> attributes, IChangeToken token);

答案 1 :(得分:0)

我尝试过使用我在原始问题中考虑过的“IChangeSet”的方法。在这种情况下,IDirectorySource界面如下所示:

public interface IDirectorySource
{
    IChangeSet GetChanges(IList<string> attributes, IChangeToken token);
}

并实现了一个如下所示的IChangeSet接口:

public interface IChangeSet : IEnumerable<IDirectoryEntry>
{
    IChangeToken GetToken();
}

这使得编写类似这样的客户端代码成为可能:

IChangeSet result = source.GetChanges(attributes, token);

foreach (IDirectoryEntry entry in result) {
    // Do something with the data...
}

IChangeToken resultToken = result.GetToken();

即使它可以在枚举之前调用“GetToken()” - 方法(这可能是错误的),但如果在枚举完成之前调用该函数,我可以返回旧标记。

不觉得100%,但这是我现在能想到的最好的......