Another way to think of events, publishers/subscribers, etc...is to think of the cloud and the way it tends to function. In a cloud based system, any entity can register to listen for any type of event, OR can publish any event that it wants. Anyone listening, will get that data.
In your example: Taxi central could publish/push events like Shift Change, Traffic Accident as (Location), Taxi Requested at (Location), or other similar things that the entire group of cabs would be listening for. The individual cabs would be publishing things like Pickup At (Location), Drop Off at (Location), Accident at (Location); that Central would be logging for its own purposes. Other cabs could if they wanted to ALSO be listening for these same events, so that they would know where and how close other cabs are to their own location, or if there is an accident that another cab reported, or similar.
Cloud events however are a specific implementation of the event system. Its much more common to specifically subscribe to events. A cab object, when created, would immediately subscribe itself to the Central events, and the central system when dispatching the cab would make certain that it subscribed itself to that cab's events.
In this way, both objects serve the role of both publisher and subscriber. Its only really specific to a single event. In my example PickupAt(Location)
would be published by a Cab, and Subscribed to by Central. Thus, for that event, Cab is the publisher, and Central is the Subscriber. In general, Who serves what role depends entirely on the system design and what events are being created. Its not something that can really be generalized, because the entire setup could be changed, or even reversed, if you setup the events differently. That I think is the most important part.
Delegates as a whole
In its simplest term, a Delegate is a Reference. It can reference a class, more commonly it can reference a method in a class, or the call to a method in a class. It can even contain an entire method call inside itself. Its really a very versatile object, in that it can do many things. In the context of events, the delegate actually references the call to the function that implements the event.
Simple Event Code
public class c1
{
public event Eventhandler DoStuff;
public c1()
{
}
public void OnDoStuff()
{//this actually makes the event happen
if (DoStuff != null)
DoStuff(this, null);
}
}
public static void Main()
{
c1 x = new c1();
x.DoStuff += new EventHandler(ThingFunction);
x.OnDoStuff();//this is how you would fire the event deliberately
}
public void ThingFunction(object sender, EventArgs x)
{
Console.WriteLine("Something Happened");
}
c1 contains the event DoStuff
, Main subscribes to this event. When the code calls x.OnDoStuff()
from ANYWHERE, which is very handy if say you pass x, or a reference to it, into other classes where actual code is processed, then the handler way back in main, no matter how many layers deep the x.OnDoStuff()
call originates from, will execute.
Rather more specifically, once X is created, it can be passed somewhere else. As long as some function is assigned to x.DoStuff
, whenever and wherever you call the method x.OnDoStuff()
from, the function that is assigned to x.DoStuff
will execute. That is how event subscriptions work. x.OnDoStuff()
is the code call that publishes the event x.DoStuff
, and any class...in fact any number of classes, you can have multiple subscribers after all, will be able to catch the published event.