Archive for March 2010

Models in Zend Framework

A question that frequently comes up in my interactions with other developers about Zend Framework is how to approach designing models. There’s a small collection of resources and advice that I generally give on the subject, so I thought I’d write up a blog post to give people an easy place to access it all.

More than one way to skin a cat

First, there is no one “correct” way to design a model. If there were, the framework would probably have an actual model component. It doesn’t, and as Bill Karwin — former Project Manager for Zend Framework — has said, the reason for this because designing the model is your job. There are pros and cons to any approach. It’s all about finding a method that works for you, is appropriate for the situation at hand, and mitigates difficulty in long-term application maintenance.

The Model section of the Quick Start Guide and this blog post by Michelangelo van Dam includes examples of a Data Mapper approach. Zend_Db uses a Table Data Gateway and Row Data Gateway approach. Doctrine, a popular ORM library that is gaining traction in the ZF community, uses an Active Record approach. And available approaches don’t stop there. As a general rule of thumb when designing models and components in general, I recommend favoring composition over inheritance. You’ll get a better sense of what I mean by that later in the post.

Defining the model

The Wikipedia article on the MVC architectural pattern isn’t all-encompassing, but isn’t a bad place to start either. In particular, it drives home a few important points about the model that you should bear in mind.

The model is a “domain-specific representation of the data upon which the application operates.”

In a nutshell, the model handles data: storing it, retrieving it, filtering and validating it, and providing access to it.

The model contains “domain logic” that “adds meaning to raw data.”

In other words, it handles the conversion from raw data in a data source to semantically meaningful PHP objects and back again.

“MVC does not specifically mention the data access layer because it is understood to be underneath or encapsulated by the model.”

The shorter version: $model != $database. This is one point that trips a lot of people up. The model and your database are not congruent, synonymous, or in any way equivalent. Yes, 99% of the time, your model will use a database for its data source. However, models can be more complex than that: they can serve as clients to web services, limit access to data using an ACL, access data caching resources like memcached or APC, and so forth.

Designing the model

“So which approach do you use?”

Generally, the answer is none of the above. My personal preference is to keep data, in the form of plain old PHP arrays and objects, separate from logic to handle that data. Many common PHP tasks result in data already being present in either of these forms such as in its superglobal arrays, so it seems natural to just take it in the form in which it’s provided.

I define a model class that composes some other object to access the data I need, generally a Zend_Db_Adapter instance. Any methods of that model class return data using scalar types or classes that PHP supports natively. What’s great about this is that it’s fairly easy to convert data to and from these forms using type juggling regardless of the data’s origin.

“But wait, how can I encapsulate the data source within my model if I need a dependency like a Zend_Db_Adapter instance for it to be able to interact with that data source?”

This is another major question that people tend to ask. If any code calling your model first has to handle injecting its dependencies, that muddies up separation of concerns because calling code then must have some knowledge of how your model operates internally. This is a problem because, if the data source of the model needs to change in the future, all calling code needs to change as well versus only model code. There are a few ways to approach this problem in Zend Framework.

The first method involves storing your dependencies in Zend_Registry. Declare accessor methods in the model for dependencies that retrieve them from the registry only if they are not explicitly injected from calling code. This bypasses the need for dependency injection from application code, thus preserving separation of concerns, but still allows injection to be performed for unit testing purposes.

The second method is a variation of the first and is specific to the case of Zend_Db_Adapter instances. This approach involves setting your adapter as the default adapter to use for Zend_Db_Table instances in lieu of using the registry to store it. Note that this doesn’t require actually using Zend_Db_Table in order to work. This can be set from the bootstrap or application configuration file, then retrieved using the getDefaultAdapter() method of the Zend_Db_Table_Abstract class. Again, don’t forget your accessor methods so dependencies can be injected from unit tests.

Another method might be to use a service locator as a dependency in models. This serves as a layer of abstraction between models and their dependencies when it comes to controllers dealing with both. To my knowledge, the closest thing to an implementation of this in ZF is the Zend_Application_Bootstrap classes. From a controller, the bootstrap instance can be accessed as in the code example below.

$bootstrap = $this->getInvokeArg('bootstrap');

Where to go from here

Service layers are another frequent topic related to models. Those aside, I mainly suggest picking a simple model that you can prototype and try several approaches to see which you prefer. If you’ve got some ZF experience under your belt, I’d be interested in hearing about your own modeling approaches and experiences and encourage you to leave a comment on this post.

Ada Lovelace Day and Amazing Grace

So, if you hadn’t already heard, today is Ada Lovelace Day. If you aren’t familiar with it, it’s is an internationally observed event during which its participants use blogs, podcasts, videos, and all other forms of internet media to celebrate the achievements of women in the fields of technology and science. Read more about the event and its namesake or take a look at this timeline of major female figures in computing from its beginnings with Ada Lovelace to present day.

Many people choose a friend or colleague who’s helped them to excel in the field. I myself have a number I could name, but with this being the first year I’m participating, I chose instead to veer from the beaten path and write this blog post about someone I’ve admired since I began serious study of computer science in high school. The very first computer science course I took began with a unit on the history of the field. Among the other Big Names included in that unit was that of Rear Admiral Dr. Grace Hopper, also sometimes referred to as “Amazing Grace.” And did she ever live up to that name.

The first reason I admire Grace is because she was no stranger to failure or perseverence. When she applied to Vassar College at the age of 16, she was rejected because her test scores in Latin did not meet admission requirements. She persisted and was admitted the following year, going on to earn a bachelor’s degree in mathematics and physics from Vassar College and a Master’s degree from Yale. She would eventually return to Vassar to share her knowledge as an associate professor of mathematics.

While my own academic achievements are an understated far cry from hers, I relate to this quality because it took a large amount of persistence for me to complete my own degree, partly due to my admittedly lacking abilities in mathematics as compared to the requirements of the curriculum under which I graduated. I struggled, had to retake several classes due to not meeting grade requirements, but persevered and earned the degree that hangs on my wall today.

The second reason I admire Grace is the magnitude of her aspirations. In a time period when not all colleges in the country accepted women, women were mainly relegated to “lace-collar jobs” in the workforce, and the right to suffrage for women had not yet been won, Grace chose to pursue her education in a field that to this day is still predominantly occupied by men. Not only did she participate in the field, she excelled in it, contributing to technological breakthroughs that literally became the stuff of legend and the foundation for the technology that we enjoy today. Hers is truly a story for the history books, one of defying stereotypes and overcoming adversities of society to achieve something spectacular.

The final reason that I admire and even envy Grace is her contributions to the innovations of her era. In 1944, during her service in the US Navy Reserve, she served on the programming staff for the Harvard Mark I, the first large-scale automatic digital computer in the country, and coauthored papers on it and its two successors. In 1949, she became senior mathematician for the team that developed the UNIVAC I, the first commercially available computer in the country. The work she did between 1950 and 1980 resulted in the first compiler, an accomplishment to which many professional software developers today owe their livelihood. In the 1970s, she pioneered standards for testing computer components and systems for which administration would later be assumed by the National Institute of Standards and Technology. She was right there in the thick of the industry’s beginnings, making contributions that would echo in the decades to come.

Sadly, Grace passed away six years before I came to know the significance of her accomplishments to my future career and the technological state of the entire world. She was laid to rest with full military honors in Arlington National Cemetery on January 1, 1992. I regret never having had the chance to shake her hand and tell her in person all that you’ve read here just now. So Grace, I salute and thank you for the immense impact that your life and service have had on the planet you left behind. No matter where technology may take our race in the generations to come, I sincerely hope that they carry your memory with them.

Where I’ve Been

Things have been rather busy in my life recently, even though this blog doesn’t really reflect that. I thought I’d take a short post to share with any readers who may have wondered where I’ve been the past month or so.

I changed jobs a few weeks ago and the new one has kept me fairly busy learning processes, writing proposals, and beginning to work on projects. I’m getting acclimated to actively using Zend Framework again, which I’m enjoying.

I also recently launched Phergie 2.0, which was very well-received. Moving the project over to GitHub, launching the new project web site, and helping with the first round of bug fixes has kept me busy.

The ball has started rolling on getting my book published again. The ISBN has been obtained, the last round of edits is happening now, and the digital edition should be available for sale before the TEK-X conference in May. I’m hoping to have a few dead tree copies to distribute at the conference.

Speaking of which, I’ll be speaking at TEK-X, so I’ve also been working on preparing my presentation on new SPL features in PHP 5.3. I’m planning on putting my presentation content into (fairly long and embellished) blog post form, so keep an eye out for that.

I’ve been under the weather with a cold over the past week. I’ll try to find more time to blog once I’ve recovered and things have settled down a bit.