Before we talk about events... Let's consider that there are many different approaches to developing software. In my opinion, the opposite ends of the spectrum end up being:
- Knowing how the whole system looks, feels, and operates before coding a single line.
- Having an idea of what the user wants and coding to make it happen.
Well, in the first case, you know all the ins and outs of the system. You can structure your system so that almost no matter how complex it is, you can ensure that method A is always run immediately after method B which is etc... The design is completely controlled. You have a spec for how all the components work together. The problem? Well, most of this will be reserved for another write-up, but in our case there's no flexibility. If that spec changes after your complicated system is already in place, how much code do you have to go change?
Enter: Events
Okay, so I hinted at why something like Waterfall might cause some headaches, but you don't need to develop your software in an agile fashion to have flexibility. Events can help you with that!
If you're not already familiar with what an event is, it's simply a delegate that one would call when some particular criteria is met. In C#, which is what I'll be assuming for this write-up, you add event handlers to an event so that when the event is invoked, the event handlers get called (and they get called in the order that they were "hooked" onto the event). Splendid.
So what's great about events? How are they going to fix your brittle code? Well, if you approach software design in terms of components in a system and how they interact, it's really beneficial to think about how certain things react to each other. If you're planning your whole system out ahead of time, you could just always call method A, then method B, and then method C in order every time you want something in particular to happen.
But is that flexible? What happens when method B now calls an additional method, let's say method D, due to some architectural changes that had to be made. Well... That's all fine and dandy unless you have scenarios where you don't want to run D in your A,B,C method calls you have everywhere.
Consider an Example...
So, what if you had thought about it this way:
- I want B to run once A is run.
- I need an event for A
- I need to call method B in my event handler for event A
- I want C to be run once B is run.
- I need an event for B
- I need to call method C in my event handler for event B
- I want B to run once A is run.
- I need an event for A
- I need to call method B in my event handler for event A
- I want C to be run once B is run.
- I need an event for B
- I need to call method C in my event handler for event B
- I want D to be run when condition X is met after B is run
- I need an event for B (which I already have!)
- I need to call method C in my event handler for event B
- I can add a whole second event handler for event B (so I get C then D called)
- OR I can modify the existing event handler that calls method C to conditionally call method D when necessary
I'm huge on using events in my architectures, so I'll try to write up a few more posts on events and why I like them. The flexibility I just described is only one very small part of it, and it certainly requires that you shift your perspective on how components in a system interact.