Dojo and Zend: Where’s the loose coupling gone?
Posted by jonOn the eve of the release of the Zend Framework's 1.6RC, found it interesting to read Lukas' comment on Matthew Weier O'Phinney's blog about how there were outstanding issues in existing core components of the Zend Framework that hadn't been resolved, and yet the Zend_* component library was still growing and accepting new proposals.
The last comment by Martin noted that Zend_Db still had some unresolved issues for over a year.
Matthew's response was that this was a community project and that priorities are dictated as such. Personally, this doesn't affect me because I'm hedging my bets on Doctrine as an ORM layer for PHP development.
I like Matthew's response because the Zend Framework's philosophy encourages the development of loosely coupled components wrapped up in a development philosophy that encourages open contributions, financial backing (thanks to Zend, IBM, Sun and others), Unit Testing and project transparency. Here's where things go a little wonky.
Partnership with the Dojo community
While I really enjoy the implementation of Zend_Form on the server side. It allows multiple configurations, supports validation and while the decorators are a bit obtuse, on a whole, the Zend_Form libraries thin out controllers and encapsulate the concern of data entry in a clean manner.
In this point release, however it seems like there's been a whole outgrowth of Zend_Dojo_* classes that cater to doing AJAX development with the Dojo stack. I'm not sold on Dojo as a client-side framework. Past experience with it has left me trying to sort out a large, over-specialized collection of patterns that almost do what I want but not quite. I also don't like the coupling that occurs between the data set, the client-side validation and the magic rendering of panels (like Accordian's and content panes).
An alternative architectural approach
I would rather write the events, the theme, the data and the validation separately and reduce duplication in each of those patterns rather than in the UI pattern as a whole. In short, I think they've abstracted the wrong part. The same example can be seen in ASP.NET form validators from two years ago.
With Prototype, I can rapidly mock out a site with the functional requirements and use Script.aculo.us to accent the presentation with animation. My functional specification isn't muddied with fancy visuals and it lets me focus on the event handling, validation and end states rather than the fancy effects.
By using Zend_Dojo, you won't be tempted to build a well-exposed Service Layer from Zend_Controller. The advantage here is that you lead development towards service-orientation. If you need to write a Flex front-end, or a whole new business-tier, you at least have the beginnings of a web service, whereas if your working with Zend_Dojo's declarative templating syntax, you're already coupling the events, validation and data into heavily abstracted UI patterns.
This approach doesn't lead development towards the production of a refined Service Layer, but to a specialized Dojo-friendly interface with markup-generation from Zend_Form classes into Dojo markup. I would rather see a Zend_Form Service API where developers can send / receive JSON messages to inherited Zend_Form and then have the Dojo community write an Adapter that would send / receive messages from Dojo widgets.
A year or two from now, I wouldn't be surprised if people will look at the same Zend bug tracker, asking where support for Dojo went after the Zend team jumps to the next cool Javascript framework on the block and we find ourselves with Zend_Form_SproutCore or some other dependency.
Raspberry Steak
Posted by jonI don't want to turn this into a cooking blog, however lately my life has allowed me to experiment with my cooking.
Tonight: raspberry steak. It begins with two cups of raspberries, two table spoons of sugar and a bit of raspberry vinaigrette:

After a bit of marinading, we end up with this. Notice the raspberry seeds have remained part of the searing:

Steak without mashed potatos is a bit of a faux pas:

While the inside lended towards rare, this worked well with the colours. I made a sauce from tomato paste, worchester sauce and the remaining raspberries which complemented the steak while giving it a bit of a kick. The onions were lightly seasoned with dijon mustard and pesto:

I've been going back to Patterns of Enterprise Application Architecture lately to brush up on some concepts in order to apply them to PHP with Zend and Doctrine.
At the beginning of the book, Martin Fowler suggests that there's a fork at the beginning of every development road where each project either ends up attempting to use Transaction Scripts, a Table Module, or a Domain Model. He argues that as project complexity increases, the two former design methodologies start to break down, causing code duplication and unmanageable complexity.
Transaction Scripts
Organizes business logic by procedures where each procedure handles a single request from the presentation. –Martin Fowler
In PHP, a transaction script sounds like a simple function call. It could be something as simple as:
saveWishlist($currentWishlist);
saveWishlist() could easily grab $currentWishlist, which could be an object containing a wishlist and a user ID and run an INSERT statement against a MySQL database.
This ends up becoming a problem if wishlists start having alternate transactions with similar logic. For example, what if the wishlist belongs to a preferred customer, or someone of a particular region? What if the application grows and now includes wedding lists and birthday lists? Each one of these procedures would perform near identical operations against the database.
Table Module
A single instance that handles the business logic for all rows in a database table or view.–Martin Fowler
Lists are beginning to become an abstract concept in the application. At this point, a list could actually be an object that represents a table row in the database. A Table Module pattern would have a series of objects that would encapsulate rules for particular tables.
We can have a MarriageList object representing a marriage_list table, and a BirthdayList object representing a birthday_list table. In each of these objects, we would put business rules specific to each class / table.
A Domain Model
An object model of the domain that incorporates both behavior and data.–Martin Fowler
Now a one-table-per-list approach to an extent... until the marketing director calls up the CIO and says that it would be really cool if you could "share" lists with friends (since he read that O'Reilly article from two years ago about Web 2.0).
All of a sudden, lists become a complex construct in your application. They start looking more like this:

Each List object might have its own business rules based not only on what type of list it is, but also who is asking for it (is it your friend's birthday list that he's sharing with his girlfriend, or is it your own birthday list that you're sharing with your girlfriend?) The object graph above would allow some really neat code like:
$myFriends = $currentPerson->getFriends(); $myFriendLists = array(); foreach ($myFriends->getFriends() as $friend) $myFriendLists[] = $friend->getAllLists();
what we would end up with is a collection of all our friend's lists. We could do cross-referencing or reporting to see who likes what and create object graphs with entities or help users visualize common products among friends for each occasion. Note that these objects may or may not (and probably don't) correspond to rows in a database.
This kind of work is nearly impossible with a Table Module approach because modelling the person->friend (one-to-many) and correlating that with the person->lists (one-to-many) doesn't make much sense in the database directly, unless the whole application is based on list sharing. The code above could help form an Entity called FriendLists or we could make an Entity called FriendWeddingLists. Making these distinctions in code is much easier than in a normalized database.
Is a Domain Model Worth It?
I would say that in most cases, the answer to that question is no, however a lot of the tools in the Zend Framework and Doctrine facilitate the building of preliminary Domains. We can create simple object graphs and separate our models from the controller layer (anything inherited from Zend_Controller) through Repositories that aren't REAL Repositories by Evans / Fowler's definition. Regardless, they provide a coarse interface for the Controller to interact with the underlying data model.
Doctrine, MySQL and Zend_Date
Posted by jonSomething that I've found really helpful in C# is the DateTime object and how it can be natively mapped to NHibernate classes and then straight to the database.
The equivalent Doctrine code is almost as elegant. Here's an excellent example of when objects abstract you from the nitty-gritty string parsing code that would be required to do time-stamping in a database:
$today = new Zend_Date(); $newPost = new Post(); $newPost->title = 'posting for ' . $today->get(Zend_Date::TIME_MEDIUM); $newPost->createdAt = $today->get(Zend_Date::W3C); $newPost->save();
Zend_Date::W3C returns a W3C compliant timestamp, which the Doctrine Model then passes to the underlying persistence layer.
Assuming that you had a UnitOfWork class handling your persistence, you could add createdAt to all of the YAML models, and have every record stamped with updatedAt and createdAt without changing any higher level code.
Why Bother With UpdatedAt and CreatedAt?
having these two columns in a table can save tremendous amounts of time sorting out concurrency issues. They also allow you to do some very primitive reporting on your data at no cost to adding complexity to the rest of your application.
My Doctrine Model was configured using a YAML file:
Post:
tableName: post
columns:
id:
primary: true
autoincrement: true
type: integer(4)
createdAt: date
title: string(255)
Then it's just a matter of running './doctrine rebuild-db' from the command line from the Doctrine directory and it create's the PHP classes and prepares the database columns.
Using Zend_Date, you can easily do date comparisons, generate different date formats, do complex date querying and so on without having to get into the string / number manipulations.
Learn a PHP framework? Damn right you should!
Posted by jonWe must face the fact that we are on the brink of times when man may be able to magnify his intellectual and inventive capability, just as in the nineteenth century he used machines to magnify his physical capacity. Again, as then, our innocence is lost. And again, of course, the innocence, once lost, cannot be regained. The loss demands attention, not denial.
–Christopher Alexander
This week, Ian Christian’s entitled “Should you learn a framework?” ended up on PHPDeveloper. The article is excellent, however it seems like such a non-issue in other web development circles. Would a Python developer write an application without Plone or some equivalent? What about Ruby developers?
The Java and .NET communities have moved far past such questions. Not only have frameworks been design requirement, they’ve also affected where businesses position their software development. For example, a .NET shop might specialize in traditional ASP.NET, CastleProject’s full stack, the “Guidance Packages” from the Patterns & Practices group or the upcoming Microsoft MVC framework. Within Microsoft itself, you can still pick a framework geared towards the kind of development is required.
All frameworks encourage thinking of subsystems and the development of patterns. Christopher Alexander, the building architect who inadvertently gave birth to object-oriented programming, would be proud to see people using object-orientation to solve the ever increasing complexities of software development.
Will it be possible then, for people to say stonily, that poems are not real, and that patterns are nothing but images: when in fact, the world of images controls the world of matter.
–Christopher Alexander
Writing code without a framework is like building a building without specifications for the height of baseboards and door handles and then asking the architect to design a custom tubing, air conditioning, fire and burglary standards. While Alexander was talking about patterns in visual language, I think the same can be said about software development.
Patterns exist in software and every time we write from scratch, we lose the opportunity of refining an existing pattern. Accepting that software patterns exist "demands attention, not denial."
Contributing a Tutorial for Doctrine’s Cookbook
Posted by jonI recently put together a tutorial for how to write a Unit of Work in Doctrine. Doctrine is a core piece of technology for people who have experience with Hibernate or NHibernate and want the same kind of elegant query language and ORM solution. Many thanks to Jonathan Wage for reviewing my code.