Monday, February 26, 2007

On Frameworks

Sorry for the long hiatus. I've been busy learning and doing things I've never done before, and its those things which I'm going to blog about.

I've also recently been changing gears as a developer from a scripting-style PHP programmer, to a more OO programmer (Sadly, in Java most of the time). In this transition, I'm starting to warm up to the idea of frameworks. I think I've been around enough to know at least some of the complaints lots of people have with frameworks. Over the next little while on this blog, I might bring a couple of those points up and try to lay out additional perspective on them.

Today's point:
"Frameworks are just big ugly factory factory factories too abstract and cumbersome to do any good." (example)

"If you want to develop a simple website with five to ten pages, limited access to a database, and no obligations to ensuring its performance or providing documentation, then you should stick with PHP alone. You wouldn't gain much from a web application framework, and using object orientation or an MVC model would likely only slow down your development process." (src)

The above statement from the Symfony manual pretty much lays it out, especially since the example critical article states the scope of the hypothetical project as, "...build a spice rack." For simple projects, OO and Frameworks are over-kill.

But I think the better metric for determining if a framework is appropriate is not in number of pages (indeed, frameworks often at least double or triple your number of files), but rather in scope of features and depth of functionality.

In order to determine this, see if you can identify some useful objects in your project at all. Anti-OO heads might correctly argue that objects aren't *required* so there aren't any to identify, whereas OO-heads might correctly say there are objects in every project - which is why I added the "useful" qualifier.

A useful object, IMO, is an object that reasonably encapsulates properties and behavior - i.e., an object whose properties or behavior will be re-used in multiple areas of the project - the common examples are DB, logging, emailing classes etc.

Now, if there's only 1 or 2 useful objects (e.g., spice jar and spice rack) in the entire scope of the project, OO is applicable, but maybe unnecessary, and frameworks are counter-productive (they tend to introduce upwards of a dozen or more support objects with which you also have to deal).

On the other hand, if there are half a dozen useful objects, it is helpful to handle them all in a consistent way so that you can be sure of responsibility scope, standard interfaces, access levels, coding styles, blah blah on every object in the project. OO and frameworks are meant to force you to do this. I think the main point of pain most PHP programmers have with frameworks is that forcing bit, which is what we find cumbersome.

This doesn't have to be the case. A good framework should align with your own style, and help you adopt OOP quickly and easily, without getting in the way of your non-framework, non-OO code. The framework should be instructional, but unobstrusive. In short, if your experience with frameworks is that they are forcibly cumbersome, check around for a different framework - that's why there are so many options (Zend Framework, CakePHP, and Symfony seem to be the biggies for PHP). When looking at frameworks, read thru their documentation and tutorials - the objects and logic should make sense to you, not confuse you.

However, you will probably never find The Perfect Framework, unless you write it yourself (bad move). More than likely, you will have to climb the learning curve for some framework, letting it force you to adopt some new coding practices. I think PHP programmers are a bit spoiled in that PHP has such a shallow learning curve that a framework's learning curve seems daunting in comparison. (Contrast this to Java where learning by framework is probably the easiest way to learn Java?) But really, once you grasp the core "Aha!" features of a framework, the rest tends to fall into place.

Climbing this learning curve is usually the point at which a PHP programmer finds the framework to be too abstract. Why is the Controller class hierarchy 5 levels deep? Why is there an interface defined if it doesn't DO anything? I think the natural inclination of PHP programmers is to try to grok the framework by reading code. This isn't as straight-forward in OO frameworks. There's lots that goes on with OO frameworks which is implicit in the design of the objects (and the mechanisms of OOP) rather than explicit in the code. I would encourage PHP programmers to stick with it - it's necessary to brush up OO skills to fully grok any framework. But again, if you find a certain framework's code and design totally illogical, it's probably not the one for you.

All I've really done so far is explain WHY frameworks are cumbersome and abstract ... but do they do any good? It's easy to just point to Ruby on Rails as proof that frameworks can be awesome, but I'd also like to point out some of the specific reasons why this is so. (I may explore these in depth later)

Standardizing your code. This is a biggie, IMO. When you do script-by-script, ad-hoc programming, your mood, caffeine levels, circadian rhythms, or any number of other factors might change the way you write code from minute to minute. This is Very Bad for maintaining the code later on, when you need to change something and realize not only is it duplicated in dozens of locations, but each one has a slight variant in how the code is run, which means you can't just find-replace it all. Ouch.

Less "plumbing" code. Now this of course relies on the idea that your project NEEDS plumbing code in the first place. Again, if your project is small, it probably doesn't need plumbing code, and adding a framework full of plumbing code slows you down. An example of "plumbing" code is DB-access code. Any object in your project which accesses a database needs it, so it's nice to have a standardized method for doing it. And if you have a dozen objects of your own to write, why not wire them up with a framework's db-access plumbing code.

Productivity. This is not apparent while first learning the framework, but adopting a framework should boost your productivity. As stated above, you will be writing little (or no) plumbing code, instead focusing on YOUR code responsibilities, and relying on the framework for others.

Testability. Arguably not a feature of ALL frameworks, but good frameworks tend to employ good OO design, which forces YOU into better OO design, which makes your code testable via mocking objects and the like. This is another one of those things that probably turns PHP programmers off at first, but if they take the time to learn it and do it, the rewards more than make up for it. Writing tests first forces you to think about how other code will interact with the code you're about to write. And if you continue to write tests, you build up an entire battery of tests which help to keep you from inadvertently introducing bugs in the future. Tests do add some time onto your development, but they give you a great deal of quality, and confidence to modify code down the road.

That's about it for now. I've actually enjoyed the Spring framework a good deal in my Java work. It inspired me to go looking at ZF, Cake, and Symfony, which I think are also pretty good frameworks for PHP. If and when I need to build a sizeable PHP project of my own, I'm sure I'll be using one of them, or something similar.