As I try to get my own head around the ongoing development of Zend Framework 2 (ZF2) and as I see other beginner/intermediate developers ask similar questions, I thought it would be useful – to me at least – to articulate some thoughts about how I understand ZF2 and some general concepts that could be helpful to understanding the framework. Hopefully, they will be helpful for newbies (and a few not-so-newbies) as well.
tl;dr: There is a lot of complexity in ZF2 that enables maximum flexibiltiy. I suspect that at some point in the future, much of this complexity can be wrapped in an easy-consumption layer that masks it for those common use-cases that do not require that flexibility.
Generally, I see the following as some of the core ZF2 ideas:
- MVC and dispatch cycle
- Dependency Injection (DI)
- Modules as first-class citizens
MVC and the dispatch cycle
To use ZF2 as more than a component library – which is a perfectly valid use case – it is necessary to understand the general notion of MVC and the request dispatch cycle. An HTTP request comes to the web-server; internal objects representing a router, the request, the response, a dispatcher are created; the request is routed to a module/controller/action; data is populated into views which then populate the response; the response is then sent back to the client. Gotta know your MVC.
Dependency Injection (DI)
There are many resources on dependency injection – including a previous blog post – but the upshot is that if an object (the consumer) needs another object (the dependency) to do its job, then it is more flexible to pass the dependency to the consumer, rather than have the consumer instantiate it itself. This decoupling eases unit testing of the consumer, allowing you to provide a mock dependency that you know functions as expected.
ZF2 has a DI component that is used heavily in the framework code and in many of the current sample apps.
Events and Aspect Oriented Programing provide a flexible way to hook external/cross-cutting processing into a line of execution flow. As a request is processed, various events can be broadcast to listeners that perform some processing.
Examples usually cited are logging and caching. Any object that needs to do logging and caching would need to compose objects for that functionality. Since this can result in boilerplate code being repeated all over the place, or in extended class inheritance trees as we attempt to put all this into a base class. An alternative is to simply compose a single “event manager” that knows how to route events and event-specific information to those listeners, who then take action.
ZF2′s EventManager is also used in the dispatch cycle to expose various stages in that cycle to other components that wish to act at that point.
Much of what you see in the current batch of ZF2 sample apps involves specifying listeners to these events.
Modules as first-class citizens
Although ZF1 had a notion of modules, they did not act as “drop-in” buckets/bundles of functionality. ZF2 raises the profile of modules so that they can more easily contain their own autoloading, config, routes, views, public web assets, etc. Further, module-specific config can be overriden at the application-level, something which is necessary to make a module truly flexible enough to drop-in, configure, and use.
Much of the complexity that is currently exposed in ZF2 is intended to make app development more flexible. I suspect that as time goes on – hopefully even before the actual post-beta release – much of this complexity will be wrappable in an easy set of simple-use-case consumer containers that mask the complexity if you don’t require all the flexibility.