假设我需要一个发布数据的服务类,订阅者可以订阅感兴趣的数据。
我应该如何设计界面? 传递回调是不好的设计?对我不感兴趣
选项1
public int Subscribe(string code, DataUpdatedDelegate callback)
{
this.subscribers[subscriptionId] = callback;
this.codeSubscribers[code].Add(subscriptionId);
...
return subscriptionId;
}
public void UnSubscribe(int subscriptionId)
{
foreach list in codeSubscribers
remove subscriptionId
subscribers.remove(subscriptionId)
}
private void OnDataUpdated(int code, Data data)
{
List<int> interestedSubscribers = codeSubscribers[code];
foreach (int subId in interestedSubscribers)
{
DataUpdatedDelegate callback = this.subscribers[subId];
callback(data);
}
}
选项2
public interface ISubscriber
{
void ProcessData(Data data);
}
public int Register(ISubscriber subscriber)
{
return subscriptionId;
}
public void Subscribe(string code, int subscriptionId)
{
}
... rest similar to option 1
答案 0 :(得分:1)
这是一个经典的Observer模式案例,我肯定会使用选项2.使用界面可以为您提供更多选项。如果以后需要在界面中添加更多方法,则无需更改大量代码。
答案 1 :(得分:0)
我会选择代理,给予更多自由的消息有效负载,只有方法订阅不是对象,并且没有与extend / interface / mixins /等混乱。它们是Python中用于pypubsub(http://pypubsub.sourceforge.net)的C#的等价物,效果很好。
答案 2 :(得分:0)
理论上,界面一旦被释放到野外就不应该改变。如果您决定使用它,请记住这一点。
当然,代表的签名也是如此。然后,您可以始终提供方法重载和多个委托重载(例如,考虑Action&lt; T&gt;,Action&lt; T1,T2&gt;等)。
这两种技术都有其优点和缺点;也不是银弹。可能引导您采用基于接口的方法的是可测试性。如果您有一个要使用的接口,那么模拟回调可能会容易得多。再说一次,代表可能也很容易。但是,如果您正在使用模拟框架或依赖注入,那么接口可能就好了。