Don’t Put the Cart Before the Horse

April 2nd I made this undiplomatic statement (funny how Twitter practically encourages being provocative):

#ZF 2.0 is a great example of second-system syndrome.

Matthew Weier O’Phinney and I have a good working relationship. I think his work on the Zend Framework project has been amazing, both from a technology perspective and a marketing perspective. 
Matthew and Bill
So when Matthew asked me to clarify my Tweet, I was happy to reply, in the spirit of constructive criticism. These thoughts apply to many projects–not just ZF–so I thought they would be of general interest. Here’s the content of my reply:

When I’ve reviewed project proposals or business plans, one thing I often advise people is that you can’t describe the value of a project in terms of how you implemented it. Users don’t want to hear about how you used XML, or dependency injection, or unit tests, or agile methodology, or whatever. They want to hear what they can do with this product.

After reading the roadmap for ZF 2.0, I observed that a great majority of the planned changes are refactoring and internal architectural changes. These are worthwhile things to do, but the roadmap says very little about the feature set, or the value to users.

What I’m saying is that implementation does not drive requirements. That’s putting the cart before the horse.

I admit that for a developer framework, this line is more blurry than in other products. Your users do care about the architecture more than they would for a traditional application. But that still doesn’t account for the emphasis on implementation changes in the roadmap, and the lack of specific feature objectives.

For instance, some goals for the controller are described in a list of four bullet items: lightweight, flexible, easy to extend, and easy to create and use custom implementations (which sounds close to easy to extend). Then it jumps right into implementation plans.

So how flexible does it need to be, and in what usage scenarios? What does lightweight mean? How will you know when it’s lightweight? Are there benchmark goals you’re hoping to meet?

Another example is namespacing. Yes, using namespaces allows you to use shorter class names. Is that the bottleneck for users of ZF 1.x? Do you need to create a namespace for every single level of the ZF tree to solve this? Would that be the best solution to the difficulties of using ZF 1.x?

The point is that the way to decide on a given implementation is to evaluate it against a set of requirements. You haven’t defined the requirements, or else you’ve defined the requirements in terms of a desired implementation.

My view is that requirements and implementation are decoupled; a specific implementation should never be treated as one of the requirements, only a means of satisfying the requirements.

Regards,
Bill Karwin

Parrot Web Framework?

Wondering if the following idea could be feasible:

  • Architect a web framework that emphasizes Inversion of Control.
  • Implement core web framework in Parrot (now that this dynamic language platform has released its 1.0).
  • Voila! A web framework that supports any language implemented for Parrot platform.
  • Developers write plugins in any language: Python, Ruby, PHP, Perl6, Lua, C, or any other language supported on Parrot.

Although the Parrot platform is now 1.0, specific language implementations are still in various stages of development. Realistically, I would guess that it’ll be some years before the architecture above is ready for production.

How do the Proxy, Decorator, Adaptor, and Bridge Patterns differ?

A user recently asked:

I was looking at the Proxy Pattern, and to me it seems an awful lot like the Decorator, Adaptor, and Bridge Patterns. Am I misunderstanding something? What’s the difference? Why would I use the proxy pattern veses the others? How have you used them in the past in real world projects?

Proxy, Decorator, Adapter, and Bridge are all variations on “wrapping” a class. But their uses are different.

  • Proxy could be used when you want to lazy-instantiate an object, or hide the fact that you’re calling a remote service, or control access to the object.
  • Decorator is also called “Smart Proxy.” This is used when you want to add functionality to an object, but not by extending that object’s type. This allows you to do so at runtime.
  • Adapter is used when you have an abstract interface, and you want to map that interface to another object which has similar functional role, but a different interface.
  • Bridge is very similar to Adapter, but we call it Bridge when you define both the abstract interface and the underlying implementation. I.e. you’re not adapting to some legacy or third-party code, you’re the designer of all the code but you need to be able to swap out different implementations.

I’m posting to my blog the questions I’ve answered on StackOverflow, which earned the “Good Answer” badge. This was my answer to “How do the Proxy, Decorator, Adaptor, and Bridge Patterns differ?