Friday, October 12, 2007

Re: An Open Letter to the Ron Paul Faithful

Mr. Wastler,

I don't want to simply rant or YELL at you, but I'd like to make a few points in response to your pseudo-accusatory remarks directed at Ron Paul supporters.

First, when you say that, " ... these Internet polls are admittedly unscientific and subject to hacking," you are incorrectly implying that other "legit" polls are not so. As I understand it, a "traditional" poll method leading up to primaries is to call 400 land-line numbers of previous primary voters. This alone introduces selection bias which detracts from the "scientific" accuracy of results.

Then, you go on to conclude that, "Our poll was either hacked or the target of a campaign." Now, whether or not your poll was hacked can only be known by CNBC and your web administrators. But since your core business is to deliver accurate financial information to the public, one would hope the security and reliability of your information isn't compromised. To give you the benefit of the doubt, we'll assume that your website is reliable and, also assuming very little "legit" Ron Paul support exists, that the poll was "the target of a campaign." Is this not, for better or worse, the way our political system works? Isn't the primary vote, the presidential vote, and the votes for every other elected position in our government the "target of a campaign?" So clearly, this isn't a sufficient reason to remove the poll, or else you would also have to remove coverage of every vote ever conducted. Your reasoning doesn't add up, so to remove *this* poll is to censor and edit facts based on some other judgment. If the actions of a well-organized campaign of individuals, acting within the rules *you* establish, makes a poll un-scientific, then how much more-so does your action of censorship?

Though your "show of hands" analogy is an admiral objective, you either intentionally refuse or ignorantly fail to see where it breaks down. It seems the poll was meant to be a "show of hands" of a certain or select few people in a certain or select space you consider to be "scientifically" representative. What actually happened is that masses of people from outside your pre-supposed space poured in to demonstrate not just their support they have for one of the options you were offering, but also to indirectly demonstrate the clumsiness and inappropriateness of your selection of individuals and space. Admittedly, this is more a criticism of all of "old media" than your poll specifically, but your poll is just another example of new forces at work in our country, and in your industry specifically. I.e., "old media" used to be the ' ... well-organized and committed "few" ... ' guiding ' ... a system meant to reflect the sentiments of "the many"' but that is changing. You should be worried.


P.S. There are others who want to talk to you.

Thursday, June 21, 2007

Ron Paul Excluded in Iowa, pt. 2 electric Bugaloo

Original digg post

I try not to post about political subjects, but this debacle is just too ripe and Ron Paul is just too cool for me to follow my normal political blog silence. Give an idiot a microphone, and I'll use it...

Ron Paul is being excluded from an upcoming presidential candidates' forum sponsored by Iowans for Tax Relief and Iowa Christian Alliance. Now, they have every right to exclude anyone they want, and no-one is arguing about that. But, if you know anything about Ron Paul, you're shocked to think that these two organization would exclude Dr. Paul, of all people. Ron Paul's campaign posted the public contact information (taken from their websites) for these two organizations and encouraged supporters to call and question the action. Apparently, the response is overwhelming the organizations, and a local radio show picked up the story and interviewed parties from both Ron Paul's campaign (Kent Snyder), and Ed Failor from Iowans for Tax Relief. The result is a pretty comical display of Failor's total ineptitude in explaining any kind of rational argument.

In response to the simple question: "Why was Ron Paul excluded?" he offers the following answer a number of times: "Because we drew a line of exclusion months ago." But this is nothing more than saying Ron Paul was excluded because he was excluded. It's circular non-sense.

Failor also offers up a dog's breakfast of off-the-cuff trite arguments in a scattershot manner.

Failor also tries to explain the exclusion by saying that they have an obligation to be educational and can't slant or bias their invitations towards people who favor any certain political agenda. But cutting taxes is already a political agenda, and the other candidates invited have pro-tax-cuts agendas, just as Ron Paul does - though none of them have the 100% record he has.

Failor then tries to explain that the exclusion of Ron Paul is done on a basis of credibility and that Ron Paul has less than 1% support in popular polls. However, Tom Tancredo consistently scores lower than Ron Paul and he was invited. In addition, Ron Paul's rise in internet popularity is nothing less than meteoric.

Failor says that they can't alter their lineup for logistical reasons. But he also says they are non-partisan and so they have to invite all candidates - not just Republicans - and they have to account for the possibility that ALL invitees could attend. If that's the case, then clearly, the event could have accommodated many more speakers - the Democrats who were invited but refused.

Failor tries to say that because they have to put on events that are reflective of what their members want to see, and because only a tiny portion of the response they've gotten has been from Iowans, that they were correct in their exclusion of Ron Paul. But Ron Paul's national popularity does not imply un-popularity in Iowa. It's a logical fallacy, and it doesn't prove anything.

Failor also tries to say that Ron Paul's supporters exhibiting "fringe-type" behavior shows that Ron Paul is not a serious candidate. He says supporters have called his home phone at all hours and said rude things to his family. But Snyder explains that the campaign only published the already-public contact information from the two groups' websites, and nothing more. Ron Paul's campaign is every bit as credible, based on its behavior, as any other candidate.

It seems to me this organization should have invited Dr. Paul first and foremost among all candidates, or at least that they should have jumped on the opportunity to get such a great speaker added to their forum. Instead, they've decided to be completely inflexible for a bunch of poor reasons. That's their prerogative, I suppose.

read more | digg story

Friday, May 18, 2007

Continuous Integration

This is another Agile/XP practice with which I'm fairly happy; although I haven't yet seen it live up to its full potential, that potential is great enough to make me a believer.

Continuous Integration is a process that completely builds and tests code frequently. The "process" usually takes the form of a dedicated server running special software that continuously performs a series of tasks similar to the following:
(though apparently this process can be un-automated by using a rubber chicken)

1. Perform an update from the code repository
2. If changes are found, run a build (compile, test) of the latest code
3. a) If successful, package the latest code for deployment or b) If failure, report failure

Although I'm a fan of CI, it seems to be a more complicated practice than TDD. Though my experience may be tainted by bad hardware + software on which our CI depends.

CI requires that you maintain an automated build script. This isn't a tall order amongst Java and other compiled-language developers since projects of any moderate size need an automated build to simply compile and to separate source code from compiled code.

Interpreted languages are a bit different, though, in that they can usually be tested immediately upon edit. As such, automated build scripts are a bit more un-common for software written in interpreted languages. But most interpreted language software projects of any moderate size do have a consistent process for deployment, even if it's as simple as: make db changes, move files - and most interpreted languages have builders to automated this consistent process. In PHP, I've been looking at Phing.

CI is really most helpful when the build process includes a solid test suite. (Defining "solid test suite" is an exercise left to the reader.) With a solid test suite, CI can help you catch bugs earlier than usual because it typically re-runs all those tests after every check-in.

In addition, CI gives creates a vast sequence of clean builds similar to the "nightly builds" you hear about in open-source projects - a finalized packaged release of the project ready for deployment.

Finally, if you ensure that your CI platform replicates your target production platform(s), you can use it as a reliable measure of your project's production-platform readiness. This can be a double-edged sword, however - if your CI platform is different than your target production platform, it can give you false confidence of production-readiness, and even cause problems that aren't caught until later in QA or worse, actual production.

As with TDD, the benefits are not without drawbacks and you should weigh them for your own project before deciding if/which/how Agile practices are adopted. CI has the above benefits, but it is also a fairly complicated development platform for which engineers will be primarily responsible - it sometimes requires a good deal of time and attention to keep going. You still have to judge for yourself if it fits into your project, goals, and style.

Wednesday, May 16, 2007

Yet Another Tutorial

Not sure what's come over me. Must be all the Coke ZERO. In any case, this tutorial is a continuation from my previous tutorials to setting up an automated build using Phing.

Tuesday, May 15, 2007

Test Driven Development

I've read a few anti- and pro-Agile rants in the past couple days. Because I'm somewhere in between, I can't really rant in either direction. Instead what I might try to do is give my opinion on the actual effects I've noticed from some Agile/XP practices on my own coding. Note that I'm probably only picking out the ones I like, so my posts on the subject will betray a pro-Agile bias. But, the sparse number of posts will hopefully balance the scales in demonstrating that there are only so many Agile/XP practices about which I actually care enough to write.

I'm a fan of Test Driven Development. I don't do TDD 100% of the time, and there are quite a few things I'm not sure how to automatically test (CSS tweaks, anyone?). But I agree with just about all the benefits I read in this pro-TDD article, though I'll re-arrange their listing by my personal opinion of their importance:

When you follow ... TDD, all your code will be testable by definition! And another word for "testable" is "decoupled". In order to test a module in isolation, you must decouple it.

When I use TDD, it forces me to write "decoupled" code. "Decoupled" is one of those magic words programmer types say to each other in intellectual flexing competitions. But TDD shows what it really means - code that can be isolated. The benefits of isolated/decoupled code are numerous - re-usability, less duplication, more concise, and I'd also say "testability" is a benefit.

This is not to say that you have to use TDD to write decoupled code. There are much smarter and more disciplined developers than myself all over who write excellent code without using TDD. But for me personally, TDD forces me into just enough structure and pre-code analysis to keep me from writing messy code that will need cleaning later. Speaking of which ...

Why don't we clean up code that we know is messy? We're afraid we'll break it. But if we have the tests, we can be reasonably sure that the code is not broken, or that we'll detect the breakage immediately. If we have the tests we become fearless about making changes. If we see messy code, or an unclean structure, we can clean it without fear.

The "safety net" feeling you get from gradually building up a big suite of automated tests is, like all "feelings", impossible to describe, but I'll try to relay an anecdote which might help.

I still don't consider myself a Java programmer, although I spend at least 50% of my time programming in Java. I don't "feel" comfortable in Java. But, in the course of our development, I made at least one deep and far-stretching re-factoring (more fancy talk for "change the guts of the code without changing its behavior") to maybe 30 different Java source files all over our code-base, with no hesitation before committing. My uncomfortable Java feelings were superseded by my comfort in the fact that all 800+ tests passed after I made the change. So I'm wasn't afraid of making the needed changes, even in a language in which I'm uncomfortable, because all the code was covered.

Again, this doesn't mean someone can't make sweeping changes unless they have tests covering all their code. I've simply noticed myself indeed becoming more fearless when I myself have to make those kinds of sweeping changes.

Have you ever integrated a third party library into your project? You got a big manual full of nice documentation. At the end there was a thin appendix of examples. Which of the two did you read? The examples of course! That's what the unit tests are!

This particular benefit is quite a distance behind the previous two. Mostly because the kind of example code you find attached to "nice documentation" is a better reference than unit test code. Unit test code is oftentimes performing some superfluous tricks for isolation, and/or hard to understand. It could be argued that if the test code is hard to follow, the tested code's design is to blame. But I think personally I'd rather move extra verbosity into my test code and keep my productive code clean. Could just be a matter of personal preference.

However, unit-tests are useful in understanding the intended use of the tested code. And programmers are more likely to spend their time to write test code that benefits themselves (see above) than they are to "waste" their time writing example code which benefits only others. So, lacking the refined, formal example code, unit tests can act as use-case specifications. (Though not 100% comprehensive design specs, as some might say.)

There are a few anti-TDD points with which I also agree...

For many, TDD is a new way of programming. As such, it has an associated learning curve, requires new thinking patterns, and takes time before it is comfortable to someone. However, I have found TDD easier and more enjoyable to adopt than Java. Some might say that isn't high praise for TDD, but to those people I would say, "Well, at least it's simpler than Java." TDD can be practiced in the language of your choice, and you will probably find that TDD resources from within your preferred language can really help to match your existing programming style with TDD.

TDD results in a LOT of code. In the course of adding tests for the ZF Tutorial app, I realized I was adding verbose testing code to already-verbose MVC code. Indeed, the test code for the controller was more code than the controller code itself. This is a simple fact of TDD - more code. There's no getting around it. You simply have to decide if the benefits of TDD outweigh its drawbacks, such as this one.

We have run into problems where our 800+ test suite takes a significantly long time to run (~10 minutes). This can be a real pain if you're working under strict CI rules in that every change you make, even that pesky css tweak, is supposed to be sent thru that test suite before committing to your source repository. Typically, though, once developers have the hang of TDD, they know what kinds of changes really need the entire test suite, and what kinds of changes can be simply checked-in, or can pass thru only a sub-set of tests. But the pain still exists in that you have an extra step of responsibility between writing your code and committing it. Again, weigh the benefits of TDD against this drawback, maybe come up with a compromise of some kind.

Thursday, May 10, 2007

More tutorials

I've been neglecting my blog, but I've been working on more tutorials:

1. Tackling the Refactoring challenge from the Getting Started with ZF tutorial
2. Selenium Testing with PHPUnit

Wednesday, April 25, 2007

Controller Testing in Zend Framework

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:

Thursday, April 05, 2007

More on design patterns

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.

Before joining SourceForge, I was okay in a few languages - Java, ColdFusion, WebMethods (shudder), Javascript, SQL, XSL/XPATH - and I was pretty good in one language - PHP. The first couple months at SourceForge were simply LOTS of PHP with a bit more architecture than I was used to - caching, entity objects, a Smarty view layer - but not much different than the PHP coding I had always done.

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.

Monday, April 02, 2007

Frameworks - 10 pounds of Design Patterns in a 5 pound bag (hopefully)

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.

Monday, March 05, 2007

frameworks, licenses, etc.

I came across this interesting and relevant blurb from a Dave Rosenberg post on not using GPL for open source projects:
Spring as GPL wouldn't make a lot of sense, just like SugarCRM as Apache wouldn't make sense. (A very dumbed-down explanation being Apache is for ubiquity whereas GPL is for commercial.)
I'll take a stab at the fully-fleshed explanation.

The reason Apache is for ubiquity is because, as a permissive license, it allows the licensee to do more with the software. Most relevant, it allows the licensee to build new software on top of the licensed software - a derivative work - but close-source the new software. This makes Apache-covered (or more generally, permissively-covered) software a suitable selection for a wider audience - those that won't (or can't) return their own contributions to the community AND those that will.

The reason GPL can be said to be a more commercial-friendly license (from a project admin perspective) is because, as a viral license, it requires that any modifications made by anyone must be returned as open-source software as well. So a potential competitor cannot "steal" your code (it is free for use anyway), but even furthermore, they cannot improve upon your offering without returning those improvements to you as well - competitors will actually help you.

Now, back to frameworks. Spring, Struts, Tapestry, Google Web Toolkit, Zend Framework, CakePHP, Symfony, Ruby on Rails - all of these use permissive licenses. The reason, of course, is that frameworks are intended to build other software. And that other software won't always be open-source. But it's important for any framework to have a strong and active community in order to enhance the framework itself, so you want ubiquity and popularity over "purity".

If Spring, or any other framework, were licensed under the GPL, then all software built on top of the framework would also have to be GPL. I won't say that this never makes sense - it could be the framework author's intention that the framework only be used to create more free software. It wouldn't make sense if the author intends for the framework to be used in as many software projects as possible.

However, most of the frameworks I mentioned are licensed under Apache License, Version 2.0 (or other similar licenses), and apparently incompatible with GNU GPL. This is just another GPL annoyance to me. These frameworks are clearly good free software, and have adopted a widely-used permissive license in order to foster popularity and community participation. I'm all for free software, but when I use any of these frameworks in a free software project, I'll be using a BSD license.

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, " 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.