聽起來像你應該使用觀察者模式,而不是讓消費者決定哪個數據包發送到哪裏。
// implement this interface in all forms
public interface IPacketSubscriber
{
void HandlePacket(Packet packet);
}
// like this
public class SomeForm : Form, IPacketSubscriber
{
public SomeForm()
{
// subscribe in some way here.
YouSingleton.Consumer.Subscribe(1, this);
YouSingleton.Consumer.Subscribe(12, this);
YouSingleton.Consumer.Subscribe(25, this);
}
public void HandlePacket(Packet packet)
{
// got packet here
}
}
// Keeps track of all subscribers
public class SubscriberList
{
Dictionary<int, List<IPacketSubscriber>> _subscribers
= new Dictionary<int, List<IPacketSubscriber>>();
public void Subscribe(int packetId, IPacketSubscriber subscriber)
{
List<IPacketSubscriber> subscribers;
if (!_subscribers.TryGetValue(packetId, out subscribers))
{
subscribers = new List<IPacketSubscriber>();
_subscribers.Add(packetId, subscribers);
}
subscribers.Add(subscriber);
}
public void Publish(Packet packet)
{
List<IPacketSubscriber> subscribers;
if (!_subscribers.TryGetValue(packet.FunctionId, out subscribers))
{
subscribers = new List<IPacketSubscriber>();
_subscribers.Add(packet.FunctionId, subscribers);
}
foreach (var subscriber in subscribers)
{
subscriber.HandlePacket(packet);
}
}
}
// changes in the consumer class
// composite pattern & law of demeter, do not expose the subscriberlist
public class Consumer
{
SubscriberList _subscribers = new SubscriberList();
public void Subscribe(int packetId, IPacketSubscriber subscriber)
{
if (subscriber == null) throw new ArgumentNullException("subscriber");
_subscribers.Subscribe(packetId, subscriber);
}
protected void OnReceivedCompletePacket(Packet packet)
{
_subscribers.Publish(packet);
}
}
然而,您可以將事情分開多一點。表格並不需要知道消費者,只是他們可以從某個地方接收事件。讓我們用知識和創造另一個接口:
public interface IPacketDispatcher
{
void Subscribe(int packetId, IPacketSubscriber);
}
,然後簡單地改變,因此,這些表格使用的界面,而不是(取決於你如何暴露調度/消費者的形式)。
這個小小的改變使得它很容易測試你的表單並改變將來如何接收數據包。