Ouch, the previous post here was pretty bad. Messy design and it didn't even work correctly. A better guide on the topic is here:
Monthly Archives: April 2007
Design patterns in the context of frameworks is a nice opportunity for me to take a break from my framework posts. I've been reading a bit on design patterns as a result of that previous post, and the poll activity on the Tulsa PHP Users Group.
In my readings, I came across this old post from the Loud Thinking blog re: Patterns & Practices over languages. Good stuff, and I'll recall my related personal experience.
I was exposed to a pretty sophisticated Java architecture when I joined the Marketplace engineering team. But, my main task initially was to build a few simple wrapper classes that would allow our PHP scripts to communicate with the Java backend over STOMP to a message queue system (ActiveMQ, specifically). This would let us continue to write simple (display-oriented) PHP scripts which relied on the sophisticated Java backend for most logic. I still like that idea, and think it can work well if given proper time and attention.
But as we faced mounting time constraint pressure, and in the interest of leveraging our available talent pool, we stepped away from using STOMP and took out most of the PHP code - save for a proxy-type controller which speaks to the Java app server and some helper classes. We started using the Web MVC module of the Spring framework (in addition to the Core, Testing, Transaction, and Hibernate modules we were already using), and were therefore implementing everything, including display via JSP, in Java. So I poured over Spring reference material. (Highly recommended book)
It was quite a (beneficial) learning experience for me. As I learned (and accepted) the Spring approach, I found that I started to care less and less about Java - it just happened to be the language in which Spring is written - and I cared more and more about the ways in which Spring worked.
Those "ways" are, of course, design patterns. Inversion of Control, Object-Relational Mapping and Active Record, MVC, Front Controller, Command Controllers ... these are all just "ways" of doing certain things, solving certain problems, that are common to many systems. As I said, in learning Spring, I'm appreciating these patterns more than the Java language.
This is what lessened my resistance to frameworks, so much so that I became a fan of (some of) them! But, still having fondness for PHP, I started looking for PHP frameworks which work in the same ways that Spring does. But, it has really changed my perspective from analyzing languages based on syntax, (or types, or whatever) to analyzing languages based on the availability of design pattern implementations.
In this respect, and from my searching, I still think (though it may still be simple bias) that PHP is the best language available for the web. There are many PHP MVC frameworks (look at all the ones in the comments as well) which implement nearly all the best proven design patterns for the web. There's enough choice out there that PHP engineers can choose not only the design patterns to use, but also between many different styles of each design pattern. And of course, because PHP is so easy, it doesn't take an "architect" to craft their own style implementation of a favorite design pattern. (like the Active Record implementation I referenced in my last post.)
It was a big step for me to stop focusing on certain languages and instead focus on design patterns. I think it's been a big step upwards in my engineering aptitude/skill/whatever. And the more design patterns I learn, the more I realize there are so many others I don't know that could make my programming even easier. Sadly, I'm nowhere near the competence needed to recognize the "informal patterns" (i.e., unnecessary repetition/duplication) in my own code, but hopefully I'll get there.
For now, I'm still just learning my way into the topic and very glad I have an opportunity to do so.
I was inspired to write this framework-related post when I read Dirk Merkel's "Practical Active Record in PHP" article from the latest issue of PHP Architect. Ironically, I was inspired because the PHP framework I'm most excited about (Zend Framework) has, AFAIK, chosen to use a Table Data Gateway pattern instead of an Active Record pattern, which I think is not quite as intuitive or easy to use. But a comparison of those two patterns is not only off-topic for this post, but well beyond my analytical qualifications.
Instead what I'd like to point out is the fact that all good frameworks should help programmers implement good design patterns. Programmers uncomfortable or unclear about frameworks might also be uncomfortable or unclear about design patterns, but design patterns are just ways of expressing common solutions to common problems, and frameworks can help teach good patterns. The web-proven ones that come to my mind first are MVC, Front-Controller, and Active Record, but there are many many more.
If you want to fully grok the Active Record pattern, you should of course read code & articles - like the article I mentioned above, or perhaps this article, or any other resource on the subject. But, since design patterns are common solutions to common problems, you don't want to re-write Active Record code every time you use a database in your applications. Instead, once you know how the Active Record pattern works, you can look for a framework which gives you an implementation of the pattern with an interface you like.
This is a much better approach to learning design patterns, IMO, than to learn design patterns outside of a framework. I find that resources covering design patterns without a framework tend to be overly abstract. Pattern implementations inside frameworks tend to constrain their context to the framework's intended use. I.e., you can learn much more about MVC theory by first diving into setting up an example Spring Web MVC application than you can by reading an abstract MVC blueprints paper.
When writing an application with a framework, you might get the feeling that you're dumbing yourself down - that you're relying on the framework too much and therefore becoming dependent on the way it works, or locking yourself into an architecture you don't fully grok and therefore can't fully debug. While that's entirely possible, it's more likely that, given the framework is reputable and has a solid architecture, you're actually relying upon good implementations of well-proven design patterns, and learning all about them in the process. This is not only good for your application, it's good for you as a programmer.