I read a post by Matthew Weier O’Phinney about aspects and subsequently a post by Garret Woodworth about aspect oriented design and I was chuckling a bit to myself. The contents of the posts where not comedic in the least but I was amused that I always referred to aspect oriented programming as a “hook system”. From Wikipedia – “aspect-oriented programming (AOP) is a programming paradigm which aims to increase modularity by allowing the separation of cross-cutting concerns. AOP forms a basis for aspect-oriented software development.” In my own use I had some functionality that didn’t fit well in some of the silos in my application and I needed a way to execute functionality throughout the site (cross cutting concerns) without baking it in every model.
For me that meant that when certain actions were taking within my PHP application e.g. creating a user or creating and article an event would be dispatched and different modules that subscribe to that event can act accordingly (which I also learned is a pattern called Signal Slots which is like having a baked in version of the Observer Pattern that I’m more familiar with).
I had always liked that WordPress provided “hooks” for plugin developers. I then had another taste of AOP in Code Ignitor’s plugin system. When I moved to Zend Framework no such thing existed and I went scouring the internet for a replacement. Unfortunately I didn’t know the official name for it so searching using terms like hooks and plugin didn’t yield much. For a few years I extended Zend’s controller plugin architecture (with some difficulty) and made do with what I had. Fast forward to my latest project Wetawa, I took the time to do more research and I found that symfony’s Event Dispatcher library did the job. Below are pros and cons
- Functionality that are applicable to different models now have a common place to live. In practice I make use of it in:
- Emails (send an email to a user when this happens)
- Reward systems (user can get a badge when this action is taken)
- User notification
- Activity Streams
- Makes it easy to add new functionality. Developers can add functionality without needing to know too much about how the larger application works. We’re on a 1 week release cycle and a lot of the new functionality we add tend to be good candidates to put in a “plugin”.
- Makes it easy to remove functionality. This is just as important as making it easy to add. If something is wrong with the site it’s easy to disable “plugins” until it’s sorted out (this may rely on implementation).
- It can be difficult to keep track of what events are being fired and the data that they contain. When creating an event is as easy as calling notify on an EventDispatcher they can be used fast and furious. There isn’t a way to enforce that make up of the event’s arguments
- Plugins can slow down the original action. If you create an email plugin that sends an email from PHP then you can have problems. The user will submit a comment and wonder why is nothing happening (there are other flaws in there as well but it’s an easy mistake to make)
- Plugins can change the data in unpredictable ways. So if plugin A is a filter plugin B might be operating on filtered content
In general I’ve been pleased with using Symfony’s EventDispatcher in my Zend Framework applications and I am glad to see that this functionality will be a first class citizen in ZF2.