Programming to Interfaces > Programming to Implementations

Over the last couple of months there is a concept in object-oriented programming that has been bothering me. This is the notion of ‘programming to an interface, not an implementation’. This is a principle I first learned about when reading “Design Patterns: Elements of Reusable Object-Oriented Software” and then further solidified when I read “Head First Design Patterns”. So when I say “programming to an interface, not an implementation” what exactly do I mean? Bill Venners interviewed Erich Gamma (interview here), one of the “Gang of Four” that co-authored “Design Patterns”, for Artima Developer during which time he asked the same question. The paraphrased answer is that it helps to limit the introduction of dependencies in your code. Limiting dependencies makes your code easier to test, easier to deploy and easier to change.

What is the problem?

You may now asking, “Mike, why does this bother you? It seems like a straightforward concept and I can’t imagine that you would disagree with it.” Well, you are mostly correct. I don’t at all disagree with this principle of reusable object-oriented design. In fact I try to embrace it. The reason it is bothering me is because I don’t believe it is really that simple of a concept and it is ‘accidentally’ ignored by developers quite often.

Story Time

So, lets go back a couple of months. As some of you know (and most of you don’t) I am currently a lead developer for a loan management platform for Selling Source, Inc. Part of my job as a lead developer is to oversee the architecture of our software and make sure it is going in the right direction. One of our projects at the moment is to revamp the search functionality of the software. I’ll try not to bore you with too many details (if you want more maybe I’ll write TWO blog posts this quarter.) We are denormalizing some of the frequently updated (and obnoxiously wide) tables involved in searching in order to allow moving indexes off of the primary tables in order to improve the update and insert speeds on the primary tables while improving the search speed in the new tables. While doing this we also decided it would be a good time to cleanup some of the code related to searching. One of the ideas was instead of building queries with string concatenations as weare currently doing we could utilize a ‘query builder’ to create the query. This would allow for more extensibility as responsibility for building the query would reside in an object that could be modified and manipulated much more elegantly than a string.

In the interest of not reinventing the wheel I had one of my developers research other, already existing query builders. The results of his search pointed us to the Zend Framework query builder: Zend_DB_Select. Now I did have a few requirements in my head for what I would like to see out of this external query builder. This first one being that I wanted it to be stand alone. I did not want to have to bring in a bunch of extra baggage that I simply did not need. I was not looking for a framework, we already have one of those. I was looking for a component that we could plug into our existing framework.

Therein lied the problem with Zend_DB_Select. If you look at Zend_DB_Select from the view point of “What are its dependencies?” You will quickly find that there is a class wide dependency on Zend_Db_Adapter_Abstract. This is an abstract class that essentially acts as a wrapper for the existing PHP database libraries. It provides a wealth of functionality including a unified interface for database interaction, a hook for a query profiler and some utility functions. I am sure in the grand scheme of the Zend Framework this is a very good and worth while class. However I would to make the argument that there is no reason for Zend_DB_Select to have a dependency on this class and the basis for that argument is an aspect of limiting your dependencies by truly programming to an interface.

How We Can Use It

So there are four ways that I would be able to use Zend_Db_Select as it is implemented right now.

  1. Change my code to utilize Zend’s db adapter for all of its connection needs. While the Zend adapter may well be better than the one I am using, I already have established use in over 100,000 lines of code of our own database connection classes. I just need to redesign our search code. Replacing all uses would be completely outside of the scope which in the business world is a bad place to be.
  2. Create a Zend_DB_Adapter instance whenever you want to use the query builder. This is not a very good option either. We are using InnoDB for our database. InnoDB performance suffers pretty much linearly with the number of open connections. Creating two connections to the same database on most every request is just a bad idea.
  3. Create an extension of Zend_DB_Adapter that decorates (wraps) an existing instance of my connection object. Of all three options so far this one is the most appealing. That being said I still do not think it is ideal. The database connection libraries we use at my office is much more encapsulated than the Zend counterpart. There is alot that Zend_DB_Adapter does that is not in our connection class, it is spread out to other classes such that it can be loaded on an as needed basis. This would make it take some time to write an adapter and would still necessitate us bringing Zend_DB_Adapter into our code base for basically a single purpose.
  4. Modify Zend_Db_Select to remove the dependency on Zend_Db_Adapter_Abstract. This is actually the path we are currently exploring. The large downside to this is that we won’t be able to quickly get the upgrades or bug fixes from Zend Framework. However I am not too concerned. What we need this class to do is significantly more limited than its current feature set so we will be able to shrink it significantly and with less code comes more stability or at the very least fewer things that could break.

We have identified that this dependency on Zend_Db_Adapter_Abstract is going to cause us all sorts of greif. Lets look at WHY Zend_DB_Select is dependent on Zend_Db_Adapter_Abstract. First, Zend_DB_Select is given the Zend_Db_Adapter_Abstract instance in the constructor. It is then set to the protected member variable $_adapter. So, lets see what all in $_adapter is called throughout the class:

  • quoteInto(): 3
  • quoteIdentifier(): 6
  • quoteTableAs(): 1
  • quoteColumnAs(): 3
  • limit(): 1
  • query(): 1
  • getFetchMode(): 1

The first thing you will notice is that all but 3 calls are to methods that are responsible for quoting an object. Now, indulge me for a moment and imagine that those were the only calls made. Why should I need a full fledged connection adapter object to perform quoting? I do realize that some quoting operations depend on the connection (character set, rdbms differences, etc.) But this should not mean that I have to use (in some form or another) Zend’s database adapters. I don’t want to use it. Mine works extremely well for what I want to do and I am already using it throughout my application.

Moving Closer to Integration Utopia

Now, in a dream world Zend_Db_Select would already be in a state that we could easily plug it into our code without having to go with one of the above four options. What if we created an interface that had a public method for each of the Zend_DB_Adapter_Abstract quote methods? It would look something like this:

The Zend_DB_Adapter could easily be made to implement this interface (you would just have to add the interface to the class definition.) Then I could change the type hint in Zend_Db_Select’s constructor to use the new interface. So how would this help my cause? Well now I have a new option. This new option would be to create an implementation of this interface that worked with my existing connection objects. This would be significantly easier than alternative 3. The interface would be well defined and significantly smaller than the Zend_Db_Adapter_Abstract class.

From a design standpoint this interface makes more sense too. The only thing we care about is quoting. So why not specify (via the constructor type hint) that this is really the only thing we are concerned with. It would make the true dependencies of our class much more transparent. From an extensibility and flexibility stand point this is very useful.

So, we still have those other pesky three calls to the Zend_Db_Adapter_Abstract class.

  • limit(): 1
  • query(): 1
  • getFetchMode(): 1

Lets explore why these are there.

The reason why limit() is being used is because different database platforms have different ways to specify limits and offsets. For MySQL you can use LIMIT , LIMIT , or LIMIT OFFSET . Oracle from what I understand doesn’t implement limits at all. Now one thing that I find uniquely curious is that all of a sudden in Zend they have moved query building back into their adapters in a very explicit way. So what would I do? Well, since we have already established that quoting really should be connection specific and we have no identified that limits are really connection specific (by virtue of being RDBMS specific) then we could make a small change to the interface above. The first would be to add the limit() function. The next would be to change the name. It is no longer a ‘Quoter’ it is now essentially performing all connection specific alterations for our queries. So lets try out the name Zend_Db_IQueryModifier. Now before you go yelling at me for that name, let me first say that I suck at class naming. You are more than welcome to ‘insert your name here’.

This leaves us with a finding home for query and getFetchMode(). I have a problem with these two method calls. They are both used on a method called query() in the Zend_Db_Select. For the kind of object I am looking for, I don’t think these should be here. We already have a class that is responsible for executing queries. Instead of calling ‘query()’ on my query builder object I would much rather pass that object to my adapter. Which is actually what the Zend Framework implementation of this method does. If you do not want to make your adapter dependent on the query object (which I personally would not want to do either) you could have the Zend_Db_Select have a method to return the query. (Zend_Db_Select implements __toString()).

With these changes I (or anyone for the matter) could use the Zend_Db_Select class completely stand alone with no need for any additional, non-exception Zend classes.

I am a Lover, Not a Hater (Oh and I’m Stupid Too)

It is not my purpose to pick on Zend Framework. I am confident that they are not the only example of not clearly thinking through dependencies and I am equally confident that many people find Zend Framework to be very useful for their needs. They just happened to have an easy real world example of ways that code can be made better and I happened to have to spend a significant amount of time inspecting the code for reasons other than writing an article. Just to prove I am not trying to point the finger I have an example that is arguably worse than the one above and it is in code that I wrote. A bug was recently opened for PHPUnit that essentially asked me why I had type hints for the default database connection class of the database extension in several of my files. There was no real need for this. I wasn’t as interested in a wrapped version of the class as I was in simply retrieving meta data. In fact to make things even worse I ALREADY HAD an interface for this data. I just simply did not use it in this case. It was a terrible oversight of mine and is an example of even when you know better these kind of dependencies can slip by. If you would like more details I can outline them in another post.

I am Almost Done

So, at the expense of ending this ridiculously long blog posting lets go back to the Erich Gamma interview. In the spirit of programming to interfaces, not implementations, I believe you should limit dependencies to responsibilities not complete classes. If a class truly has only one responsibility, then it is probably okay to use that class name as the type hint. If a class has multiple responsibilities and you have deemed it necessary than I would strongly recommend you create interfaces to indicate the public methods for those responsibilities and use those in your type hints as appropriate.

Now, if you read through the entire interview (and I suggest you do) you will notice that Erich makes some points that might on the surface seem to contradict what I am saying. Erich states “An abstract class is good as well. In fact, an abstract class gives you more flexibility when it comes to evolution. You can add new behavior without breaking clients.” This is a very valid point. He does however go on to state, “As always there is a trade-off, an interface gives you freedom with regard to the base class, an abstract class gives you the freedom to add new methods later.” So you do have a decision to make. My issue with Zend_Db_Select turned out to be that the dependency in code was deeper than it needed to be. Sometimes you will have a dependency on an abstract class that will be perfectly fine. So long as you keep responsibilities to a minimum via composition among other means (which the second point in that interview helps with.) Then you should find it very easy to program to interfaces.

DC PHP

I will be flying out this weekend for my first speaking engagement at The 2008 DC PHP Conference. In looking at the speakers list there are a few familiar faces and quite a few new ones so it should be a fun experience all around. I will be giving 2.5 talks this year. One on Beginning PHPUnit Testing, another on Advanced PHPUnit Testing and then I will be giving a joint presentation Andrew Minerd, a co-worker of mine, on distributed CLI processes.

I am fairly excited as this is not only my first time speaking at a PHP conference but it is also the first time I have been to Washington DC. I have a profound respect for the early history of our country and I am looking forward to seeing the some of the landmarks honoring that history. In any case, if you are going to be in DC for the conference be sure to track me down, I shouldn’t be too hard to find.

Continue reading DC PHP

Las Vegas PHP Group: It’s Alive

As promised, a couple of days ago the LV PHP User Group had its first meeting. The purpose of the meeting was to see what kind of interest there was and to gather some ideas for future meetings. We had a pretty good turnout for our first meeting. I think around 20 or so people attended and we mingled and talked amongst ourselves for around 2 hours.

We are going to be having another meeting in mid to late may. The current plan is that two of us will be doing a couple of short talks, I will be talking about testing and quality assurance. We also talked about getting involved in the PHP TestFest project. The last thing we decided is that the next meeting will be in a ‘quieter’ environment. PT’s Pub worked well for a meet and greet type of meeting but would be a tad loud for any kind of presenting. It also forcluded some people from attending due to the atmosphere.

When I hear more info about dates I will post it. For those of you that live nowhere near Vegas, maybe you can use us as a way to writeoff a vacation as a business expense? 😀

Las Vegas PHP User Group

I am pleased to announce that Las Vegas finally has a PHP User Group and our first meeting is…tomorrow. I am pretty excited as I know there is a fairly decent size PHP programmer community in LV, it just hasn’t been organized yet. One of my co-workers Ray Lopez is organizing the group and it looks like we’ll have a fairly decent size group at our first meeting. If you are from Las Vegas I would encourage you to attend if at all possible! If you are unable to attend then I would highly recommend you still sign up at meetup.com so you can keep informed of future meetings.

Time:
Friday, Apr 11, 2008, 4:00 PM

Place:
PT’s PUB

310 E. Warm Springs Rd.
Las Vegas, NV 89119
Directions

Late Static Binding (LSB) forward_static_call()

I finally freed up some time to finish some quick tests for some of the late static binding patches I made and one of them finally made it into head.

The original post I had bringing up this issue was lovingly title Late Static Binding…Sorta. Basically the original patch alone did not provide a means to override a method, forward execution to the parent method and still preserve the ability for static:: to be anything meaningful. It would be turned into the syntactic equivelant of self::. I came up with a few patches to address this. After several rounds of back and forth about the patches the conversation died out with no decision. I finally resurrected the topic and was able to find concensus for the third patch (forward_static_call()).

This weekend I wrapped up a few small tests and sent the patch in and it was subsequently pushed to php 5.3 and php 6.0. Now, this is not at all the way I wanted things to work, in all honesty I think the patch is pretty hokey but unfortunately nobody really spoke up in support of the changes I wanted to make to parent:: in regards to LSB. So I thought it far more important to make sure there was a way to make sure static methods could be overridden while ensuring that access to parent methods would be unabated.

So now, if you want to override a static method and forward execution to the parent class, the safe way (in regards to static inheritance) is shown in Table2 while the (unfortunately) not so safe way is shown in Table1:

This shows an example of the differences between using parent:: and forward_static_call. I really do wish that the behavior of parent:: would just be modified to work like forward_static_call does. It would be alot less awkward and imo closer to what the average oo programmer would expect. I suppose the issue is up for debate if anyone feels like bringing it up on internals, we aren’t stuck with it until php 5.3 rolls :). The patch is even available it just needs some more vocal supporters.

In either case at least there is a way around it now…

Late Static Binding – Changes to parent

If you have been following the PHP internals list for the last few weeks you probably have seen a discussion concerning the current behaviour of late static binding (lsb) and how it seems to be unnecessarily limited when it comes to inheritance. I first posted about the limitations of the current lsb implementation as it relates to inheritance in Late Static Binding…Sorta. It has since been revived in this thread on the internals mailing list: RE: [PHP-DEV] late static binding php6.

I won’t rehash all of the arguments as you can quite easily find out my full thoughts by previous posts and on that mailing list thread. To put it simply I feel that somehow there needs to be a way to call methods in a parent class without losing the ability to reference back to the original called static.

 

This (or anything like it) is currently impossible in the current lsb implementation. I spent a bit of my extended weekend preparing three different patches to work around this problem. I just now sent them to the internals mailing list so they can be discussed. You can view this email and get a summary of the patches by viewing my recent php-dev posting.

All of the above patches are against 5.3. I was having some strange problems with the test suite in php6 so I moved onto php5.3 so I could make sure things weren’t breaking on me :P. If anyone reading this feels as strongly as I do that there should be a way to do this I hope to encourage you to make your thoughts known on PHP-Dev.

ZendCon07 Day 1

Day one of the conference is over and everything has gone well so far. I attended the extending PHP session by Wez, Sara, and Marcus. It was alot of review but it was very

informative and brought up alot of things that I tend to forget frequently. It was also good to find out that Marcus has a pretty decent american impression. In either case I

have a couple small php extension projects that I am thinking about starting now just to tinker around with some of what they talked about.

I also heard some unconfirmed rumours that database testing was brought a fair amount in the Best Practices tutorial. So if any of you were in that tutorial and have any

questions track me down.

After the tutorials were finished all of us from the selling source decided to go into San Francisco for some food and what not. We went to the Stinking Rose which billed

itself as a garlic resteraunt and it certaintly did not dissapoint. We hung around for a while to chit-chat and what not. It is my first time in San Francisco and it pretty much

has further confirmed that I am definately not a city guy :).

Today’s sessions are underway and thus far I have found myself working the entire time but I plan on stopping that after the current round of sessions is over. I am looking

forward to going to Give Your Site A Boost With memcached from Ben Ramsey and High Performance PHP & MySQL Scaling Techniques by Eli White. We will also be spending some time

today setting up the Selling Source booth. We are also sponsering the opening reception tonight in the exhibit hall which I don’t really think means anything other than we’ll

have our logo plastered in a few key places which is always nice. Also we are giving away a fairly nifty prize at the end of the conference to a random winner of a little code challenge that we put together.

If any of the fellow conference goers plan on going to the opening reception be sure to track me down and say hello. I think I am going to leave both my laptop and black

berry so there will be no distractions. I would love to talk to y’all about pretty much anything. :P.

Going to ZendCon

I will be leaving for ZendCon on Sunday. This will be my first zend con and I am really looking forward to going. I was hoping to speak at the conference about refactoring and database testing but alas it wasn’t meant to be :). I figure it gives me more time to enjoy everyone else’s talks and I can also meet the other attendees without the impending doom of everyone in a room paying attention to me.

I will be attending the conference with a sizable group of co-workers from The Selling Source and will be spending some time in our booth in the exhibit hall. If any of you would like to discuss unit testing, late static binding, or what not please come track me down. I am very interested to talk with anyone that may have checked out the PHPUnit Database extension. I have a small list of features that I am hoping to add shortly and would love to hear about any other features people may be looking for.