Jeff Carouth's blog Ramblings of a Web Application Developer

13Jan/100

Coding to an Interface

In a recent user group presentation the topic of using interfaces to enforce coding standards, ensure component compatibility, etc. was touched upon. The inevitable discussion about the definition of coding to an interface commenced.

The Literal Definition

Most people when first introduced to the concept of coding to an interface or even "design by contract" type concepts take the literal definition. At this basic level the technique means to use your programming languages OOP interface to define the behavior of the objects you will be using and accept objects that implement that interface where necessary, as illustrated in the following listing.

interface Deleteable
{
    //some methods
}

class Book implements Deleteable
{
    //implementation
}

class BookDataSource
{
    public function delete(Deleteable $book)
    {
        $this->purge($book);
    }
}

With this arrangement any methods that are necessary to prepare an object for deletion will be implemented in the Book class and the data source will only allow objects that implement the Deleteable interface to be purged from existence.

This technique is employed to allow better unit testing, for polymorphism, to ensure that objects have certain behavior, and a variety of other reasons. Coding to the contract provided by the interface is a great practice.

An Expanded Definition

While the literal definition above is definitely accurate and valuable, the interface extends into other areas. In modern software projects there are a variety of resourced one can call upon to learn about the behavior and properties of software components. Each of these resources is a part of the contract and useful as an interface to which developers should code.

Documentation

The most obvious resource for defining behavior and properties is documentation. Whether this is some sort of specification document in a wiki, in a binder, on notecards, on napkins, etc., or code comments documentation is a useful interface as long as it is maintained. Maintenance is the pitfall of using documentation as a contract because it is so often and so easily neglected.

Because documentation is most likely out of date — hey, I code in the real world — it is my last choice for an interface-defining resource. However it's better than having nothing.

Unit Tests

Thinking about it, unit tests are the ultimate supplemental contract for code. They will immediately notify the developer if the terms of the contract (the assertions) are broken. They also provide usage documentation that will help integration efforts.

In Your Code

The message I hope to get across with this post is that the concept of design by contract or coding to an interface is broader than the literal implications. Using supplemental contracts for your projects will make your projects better if only for that day in the future when you wonder why you made the decision you did.

by
2Nov/090

Excepting with the SPL

In my opinion  proper use of error handling within an application is the mark of seasoned, professional developer. It is far too often that I see code that explodes on every error or, even worse, does not consider that errors will occur during runtime.

One area that I like to make use of exceptions is unexpected input, especially in terms of function/method arguments. A lot of times the standard practice seems to be to return FALSE for invalid input, but the boolean value false should be reserved for boolean indication. Likewise, NULL should have a special connotation, semantically speaking.

In this first example, a repository (or mapper) is attempting to find a user with an id—let's assume it is a database id—that should be an integer. (This code uses the Zend_Db_Table component to abstract queries, etc.)

class UserRepository implements IRepository
{
 public function fetchById($id)
 {
     $data = $this->getDbTable()
                 ->find($id)
                 ->current();

     if (null === $data) {
         return null;
     }

     return new User($data->toArray());
 }
}

Notice there is no validation performed on the $id parameter which is pushed directly into the database table query. Granted the Zend_Db component will handle this error with minimal pain, i.e., you should be fairly protected against a SQL injection attack, but you know that your database table uses an integer for the ID column thus your application should only respond positively to an  integer value for $id.

public function fetchById($id)
{
    if (!is_int($id)) {
        return false;
    }
    //…snip
}

My first attempt (above) at validation uses the native is_int() validation function to check if the value supplied for $id is an integer. If it is not the function returns false. There is plenty of precedent behind using the value FALSE as the error state, but it is blatantly not semantic. FALSE is obviously not the user object I asked for, but it does not indicate what went wrong.

Finally, I decide to use the Zend_Validate component—for this trivial example it may be overkill, but it does the job nonetheless—to validate my input parameter for the user's ID property. Also notice that I am now throwing an exception object, specifically an InvalidArgumentException.

public function fetchById($id)
{
    $validator = new Zend_Validate_Int();
    if (!$validator->isValid($id)) {
        throw new InvalidArgumentException(
            'User ID must be an integer.
        );
    }
    //…snip
}

The InvalidArgumentException exception is one of many defined in the SPL as an extension of a logic exception. The reason for using such an exception class would be to improve the readability and usefulness of client code. When I use the UserRepository object, my client code will look as follows. When an invalid argument, i.e., a non integer is given to the fetchById() method it is obvious which code path will execute.

try {
    $repository = new UserRepository();
    $user = $repository->fetchById("jcarouth");
} catch(InvalidArgumentException $e) {
    //we passed an invalid argument, i.e., a non-integer
} catch(Exception $e) {
    //some other
}
by
9Sep/093

Professional Development with the Zend Framework: Introduction

Table of contents for Professional PHP Development

  1. Professional Development with the Zend Framework: Introduction
  2. Professional Development with the Zend Framework: Unit Testing

Talk to a random sample of developers and you'll find a wide range of opinions regarding frameworks. Some people swear by frameworks; some people swear they will never touch a framework. Regardless of your opinion frameworks do serve a valuable purpose: they are tools that are capable and quite effective at developing professional developers.

Frameworks are not unique to any one language. I've watched PHP develop from a scripting language designed to simplify dynamic elements in a personal home page to an "object capable" (snicker) language that people apply object oriented principles with. With the recent rise in available of PHP frameworks, development — professional, "enterprise", or otherwise — using frameworks is becoming more and more prevalent.

Why the Zend Framework?

Personally, I've only worked with a few frameworks and none more so than with the Zend Framework (ZF) which is why I chose it for this series. There are quite a few tutorials out there on how to get started with the framework and I don't intend for this to be a quick and easy "Hello World" tutorial. If you are after something along those lines I'd suggest reading Pádraic Brady's book Zend Framework: Surviving the Deep End. Rather, I'd like to walk through how to use the framework as a learning tool. This will be useful knowledge for even the freshest of beginners but I think it will be especially useful to a developer looking to take his or her framework-driven projects to the next level.

One benefit found in using the Zend Framework comes from its design as a use-at-will framework which means the component library is useful separate from the MVC stack. More concisely, if there is a component of the framework, e.g., the Twitter service wrapper, that you would like to use it is possible to just grab that component and run with it. (I believe the ZF team has worked hard in trying to keep components as decoupled as possible. That said, it is entirely possible that you might have to grab a couple components.)

In this series I will be using the the framework "in all its glory" including the MVC stack. As stated earlier I will assume that you understand the basics on getting your app up and running, but I will have to walk you though some places where I tend to differ from some of the conventions found in the various sources of guidelines for ZF development.

Source Code

To truly benefit from this series you will need to see the progression of the project from early stages to polished and ready for deployment. That wouldn't be difficult except that I don't know at what point you stumbled upon this series. To better facilitate housing each step I will host the code for this series on GitHub. (If you have not yet experimented with Git I — and many others — highly recommend giving it a shot.)

Each installment of this series will be a branch in the Git repository. There should be roughly one branch per installment unless there is something terribly clever or complicated and I'll try to separate it out for you.

You can browse the repository online or clone it. I also encourage you to fork the project and add your commentary. After all giving back to the PHP community is encouraged. The code is licensed under the GPLv3 free software license.

Environment

To follow along with the series you will need to have access to several tools. First and foremost you will need a copy of the Zend Framework. The release at the time of writing is version 1.9.2. I like to use the release branch associated with the current minor version as my development code base. In other words I'll pull from the svn repository branches/release-1.9 instead of the tag for release-1.9.2. This allows my development to receive all bug fixes and improvements for the 1.9.x family.

You will also need a copy of PHPUnit. Sebastian Bergmann maintains steller documentation on installing and using PHPUnit. While not necessary if you just want to gather some new practices or tips on using the framework, PHPUnderControl (PHPUC) is something I'll mention and use throughout this series. Several other tools integrate with PHPUC including PHP Code Sniffer, PHP Documentor, and dbdeploy.

I'll be using PHP version 5.2.9 on my development environment. While PHP 5.3 is the current version it's sadly likely that the adoption rate will be as slow as usual. To take full advantage of PHPUnit and PHPUC, Xdebug will also be used on my development machine(s).

Now, if I haven't lost you, let's move on to some actual developing; well, if you call using mkdir development.

The Directory Structure

At first glance, the recommended Zend Framework directory structure is incredibly complex. I know because the first time I saw my eyes glazed over. But there is a reason for the deep structure and it's masquerading around as our good friend Mr. Separation of Concerns. Take a moment to digest the structure in Figure 1.

Default directory structure for a Zend Framework project.

Figure 1 — Recommended Zend Framework Structure

Pay no attention to the little cross-hair like symbol on all the directories. That just means that the directory is in the Eclipse build path. In all this is not a bad directory structure. It has a places outside of the document root (which is the public directory, by the way) for tests, configuration files, application cache files, uploaded files, et cetera.

However, in my opinion this structure does not make sense for a production product. For example, when this project is deployed, the tests do not need to go with it. They need to be present on every developer's workstation and the build server, but the final deployment of the product has no reason to keep them around. So, my first change is to separate the tree(s) that compose the production-necessary files from the test and development files. (I'll also cheat and make the change look more impressive by collapsing the expanded directories.)

Figure 2 — Modified "ProDev" structure

Figure 2 — Modified "ProDev" structure

As you can see, we

  1. added a tools directory,
  2. added the src directory (which now contains all of our application code),
  3. removed the build sub-directory from the scripts directory, and
  4. added a directory called database with a sub-directory of deltas to the scripts directory.

The tools directory will house local copies of the various external tool libraries, e.g., PHPUnit, that are needed for the build process. I keep local copies to ensure that no matter where the project is being developed, the environment is consistent. For example, I might have a PHPUnit instance on my development box that is version 3.4 of the project but the build server might be at version 3.3. Having the local project copy — or reference, really — means that I don't have to worry about what version is installed where. I know it will work.

The src directory is where the application code will reside including the reference to the framework. Keeping it contained inside this directory allows the project's development files to remain separate from the application code that will be distributed in final form.

The scripts/build directory is unnecessary as the build script(s) belongs in the project root.

Finally, I added the database and database/deltas directory to the scripts directory to house the script(s) necessary to create and initialize the database for the application — assuming there is one. The deltas part will be confusing to you if you are not familiar with dbdeploy. Essentially this folder will contain a series of sql files prefixed by a number, e.g., 001_create_professionals_table.sql. The three digit number increments by one with each script. I don't yet know what happens after 999_x.sql because I have not made it that far in a project. We'll touch on database and delta scripts later on.

Stub the Necessary Files

The main "hello world" files in a Zend Framework application are no secret. There must be an index.php script, a .htaccess file, a Bootstrap.php file complete with an implementation of Zend_Application_Bootstrap_Bootstrap, so on and so forth. All of these files are included in the Git repository. Clone away.

The interesting bits are the unit test scripts and the build script. For the unit tests — in the tests directory — the scripts you will find in this initial distribution of the ProDevZF application are the phpunit.xml file (a configuration file used by the PHPUnit engine; a bootstrap.php script (used to set up necessary resources to run the scripts); and an AllTests.php (which is a bit strange at this point considering the test suite is empty). Feel free to poke around the contents of those files before the next installment of this series where I will explain them.

The build script is a whole different beast. Welcome to the world of Ant. If you aren't into Ant because you hate Java — or for other more noble reasons — there is a similar tool called Phing. You can probably use Phing instead of Ant but I will not because I'm using Java-based products for my continuous integration. Since build scripts in Ant are covered in great detail on the Internet (the series of tubes you are connected to right now) I will elect to not explain the build script. If you'd like me to explain the whats and whys, leave me a comment and I'll work it into a supplementary post.

Words. So many of them.

At long last this introduction is over. I appreciate your patience as I set the stage for the coming articles. I am hopeful that no other installment in this series is quite as lengthy.

by

Recent Comments

Categories

Recently Authored

Archives

Blogroll