December 21, 2009

The Apple of My Eye

This weekend I joined the great unwashed mobile masses by purchasing an iPhone 3GS. Okay, I can't lie: I was really excited to get the phone; I've been wanting an iPhone 3GS since it came out this summer and have felt like the only kid on the block without one, so I finally feel like part of the in-crowd.

Of course, the first thing I did once I got it home was start downloading apps: Facebook, Rotten Tomatoes, etc...

...which got me to thinking about the IPhone Developer Program.

A Standard account in the Developer Program is $99, which gives you access to app development tools, testing tools, and the App Store - where you can sell your app or give it away for free.

Sounds great, right? One catch.

As of right now, only Mac users can use the iPhone SDK and related development tools. Well, I'm not a Mac user, nor do I intend to be anytime soon. So, what's out there for me?

Nothing. Yet.

However, Adobe announced at the MAX 2009 conference that Flash CS5 will contain a Packager for iPhone that will allow Flash developers to target their apps to the iPhone platform. According to Adobe's announcement, the Packager will compile Flash movies down to native iPhone code, and developers on any of Flash's supported authoring platforms will be able to distribute their apps in the Apple App Store (after they've joined the iPhone Developer Program, of course).

So when do we get to see Flash CS5? Well, unfortunately there will be no public beta of Flash CS5, so we'll have to wait until the retail release sometime in 2010.

Until then, I'll be waiting...

December 10, 2009

The Patent Office Called... The Wheel's Been Invented Already


When it comes to developing software of all kinds, I feel like sometimes - more often than not maybe - we'll never learn.

I hear from purist software knobs everyday who tell me, maybe in not so many words, that when it comes to software components, in order to do something right you have to do it yourself. That is to say, even if there are perfectly good components already out there ready to be bought and implemented, it's better to just build it yourself.

To which I ask:

If you need an alternator for your car, do you go into your garage and construct one for yourself, or do you simply go to the auto supply store and buy one?

Of course, you buy an alternator for your car. But why? Well, you do it for several reasons:
  1. You do not know, nor do you care to know, how to build an alternator.
  2. You do not know, nor do you care to know, how an alternator works.
  3. It requires less time and effort (remember time*effort=money) to buy an alternator than it does to build one.
  4. Alternators are a commodity in the auto supply market, so they're fairly cheap.
I could go on with the list, but I think you get my point.

Many of the aforementioned software knobs would agree with me about the alternator, and compare it to a text input box, a radio button, a check box, etc. And, of course, in these instances their comparisons are entirely valid. However, my peers will often throw up their hands when I say that more complex components, like API wrappers for well-known web services such as Amazon S3, also belong in software's alternator bin.

The fact is that there are really very few reasons to build a new software component these days, and whether you're a software developer, a project manager, or an IT manager, you'll want to pay close attention to this list.

Business Justifications for Building, Rather than Buying, Software Components:

  1. There does not exist a stable and mature component that meets the functional and/or technical requirements of your project (not likely, but possible).
  2. Licensing agreements prevent you from using a purchased component in a commercial application (also unlikely, but possible).
  3. Building the component adds greater business value than buying the component (ie: your component will have features that currently available ones do not have, thereby giving your company competitive advantage).
  4. The cost (economic and opportunity) of building the component is less than the cost of buying the component (very unlikely). 
These are not the only 4 reasons, but they're probably the 4 biggest reasons. Regardless, unless the component you're planning to build can be justified by one of the four reasons above, then you probably should not be building it.

That said, I'm open to counter-arguments, further suggestions, questions, etc. Feel free to drop a line in the comments section below, or email me at brian (at) brian-driscoll (dot) com.

Image above courtesy of http://thereifixedit.com. Used without permission.

December 7, 2009

Building a REST (or REST-like) LAMP Web Service - Part 1

Last week a colleague asked me about web services. Specifically, he wanted to know what a web service was, and why one would deploy a web service. I answered his questions to the best of my abilities; I told him that a web service is an API that allows two applications to share data in an agreed upon format, such as XML or JSON. As for the why part, I told him that web services are deployed in situations where two or more decoupled applications want (or need) to share information.

Since he'd taken such a keen interest in web services, and since I know he's familiar with web services, I figured I'd post a brief tutorial on how to create and deploy a REST (or REST-like) web service on a LAMP platform. For the purpose of this tutorial, the P in LAMP will be PHP. I will assume that you have a strong working knowledge of XML and PHP.

Before we get started, it's worth mentioning that there is no single way to set up and run a REST web service on the LAMP platform, so in reality the method I'm going to show you today is just one way of doing it. There are plenty of other equally valid ways of setting up and running web services on the LAMP platform.

We will need at least 3 files to get started:
  • .htaccess - This file will redirect URIs to our web service endpoint.
  • index.php - This file will be our web service endpoint. It will parse URIs and pass requests to an instance of our web service.
  • webservice.php - This class will be the workhorse of our application - it will handle data retrieval, formatting, etc.

Designing the Web Service

I'm not going to get too deep into REST theory and practice here. If you want a more in-depth (but accessible) treatment of REST principles, I recommend checking out Ryan Tomayko's excellent article, "How I Explained REST to My Wife." The basic gist of RESTful web services is that they use a combination of URIs and request methods (GET, POST, PUT, DELETE) to execute a function and return a response. For this tutorial, we're going to create a web service that stores and retrieves information about a set of books.

When designing a RESTful web service one needs to consider both the URI scheme that will be used, as well as the data scheme that will be used. Let's start by figuring out our data schemes. For simplicity's sake, let's say that our web service will provide information about books and their authors.

For books, we want to store and retrieve the following information:
  • Book ID
  • Title
  • Author's Name (in Last, First format)
For authors, we want to store and retrieve the following information:
  • Author ID
  • Last Name
  • First Name
Obviously we could have a lot more information on both books and authors, but for this example what we have now will suffice. So, now, let's take a look at what we want our XML entities for both book and author to look like:

<book>
  <id>12345</id>
  <bookTitle>Learning XML, Second Edition</bookTitle>
  <author>Ray, Erik</author>
</book>


<author>
  <id>321</id>
  <lastName>Ray</lastName>
  <firstName>Erik</firstName>
</author>



If we have multiple books or authors, we'll just wrap them in plural tags, like this:

<books>
  <book>...</book>
  <book>...</book>
</books>


<authors>
  <author>...</author>
  <author>...</author>
</authors>


Now that we've figured out our data structures, we need to think about our URI schemes. Remember that we need to consider both the URI and the request method...


URI
Method
Description
/books/
GET
Gets a list of all books
/book/{id}/
GET
Gets the book specified by {id}
/book/new/
POST
Creates a new book
/authors/
GET
Gets a list of all authors
/author/{id}/
GET
Gets the author referenced by {id}
/author/new/
POST
Creates a new author.

We have both our data structures and our URIs defined; now it's time to take a look at our web service implementation.

Implementing the Service: .htaccess and index.php

We'll start the web service implementation process by setting up our .htaccess and index.php files. We'll cover the web service class implementation in Part 2 of the article.

.htaccess is a file that is used by the Apache HTTP server to determine how files on your server are accessed on a per-directory basis. I won't explain it fully here, but if you want to know more about .htaccess and how you can use it, feel free to check out Apache's .htaccess file tutorial.

For our purposes, we're going to take advantage of Apache's URI rewriting engine to redirect requests to specific URIs to our index.php file. Open up a plain text editor, such as notepad, and let's begin:

The first two lines in our .htaccess file are the following:
RewriteEngine on
RewriteBase /

The first line is fairly self explanatory. The second line simply tells the web server that the base virtual path to our web service is "/" (for more information on how RewriteBase works, read this Apache doc).

The next line in our .htaccess file is this:
RewriteCond %{REQUEST_FILENAME} !-s 

It may look crazy, but the line above is simply telling the server that it should only re-direct requests to our index.php file if the requested file does not already exist in this directory. This is useful in the case that we want to store other resources in this directory, such as documentation files.

Finally, the last line in our .htaccess file handles the redirection to index.php:
RewriteRule ^(.*)$ /index.php/$1 [L]

Once again, it looks like we have a lot of stuff here, and in truth we do. In practice, here's what the .htaccess file does:

In your browser, you type the following: http://www.some-domain.com/authors/

The .htaccess file at http://www.some-domain.com/ intercepts your request and checks the directory to see if a resource named /authors/ actually exists. If it does not exist, your request is rewritten as http://www.some-domain.com/index.php/authors/

This redirection happens on the server, however, not in your browser. So, the URI that you see in your browser is still http://www.some-domain.com/authors/

Let's move on and implement index.php. We'll start by getting the request method and path information.

$method = $_SERVER['REQUEST_METHOD']; //e.g. GET, POST
$path_info = $_SERVER['ORIG_PATH_INFO']; //e.g. index.php/authors/
$uri_parts = parse_uri($path_info);
$resource_type = $uri_parts['resource_type']; //e.g. "authors"
$request = $uri_parts['request']; //anything after the resource type

$service = new BookService($method,$resource_type,$request);
$service.execute();

function parse_uri($path_string)
{
  // $path_string is something like
  // 'index.php/authors/'
  $path_parts = explode("/",$path_string);
  $restype = $path_parts[1];
  $req = $path_parts[2];

  $ret_array = array();
  $ret_array['resource_type'] = $restype;
  $ret_array['request'] = $req;

  return $ret_array;
}

That's all you need for your index.php file. In the next installment we'll define the BookService class and provide the functionality needed to get the service up and running. In the meantime, if you have questions or comments feel free to post them here or email brian (at) brian-driscoll (dot) com.

December 3, 2009

Why External UI Testing Matters

I'm not a UI/UX person, nor do I have a degree in human-computer interaction. I'm a programmer. And today, a client is going to yell at me.

Long story short: a web application I created a while back was supposed to automatically save user-entered data, which it did - but only if the user followed a specific interaction sequence. Of course, this specific interaction sequence made perfect sense to me, our QA group, and our client's beta test group, as not a single person reported having a problem with saving data prior to the application's commercial release.

Now, almost a year after release, complaints are pouring in from our client's customers about issues with data saving. After looking at all of the potential causes of such a failure I found the cause: user interaction sequences that were not captured at any point during the design and development application, and thus do not trigger data saving.

Of course, since these alternative sequences were discovered we've added the appropriate code to save data, and the application is working well. But, that isn't going to keep me from getting yelled at by our client.

So, what have I learned from this experience?

I've learned that sometimes, no matter how thorough an internal QA team might be, they're just too close to the project to be able to see all of the potential problems that might occur on the end-user side of the application. Thus, I've concluded that on applications such as this one it is important to conduct black-box testing with users who have at most minimal familiarity with the project's deliverables. I'm confident that if we'd had someone external to the project sit down and go through the application without any prompting or coaching, the problematic UI sequences would have been captured and addressed long before the application was released.

...and I wouldn't be getting yelled at.

December 2, 2009

The Interface Will Set You Free

All too often I see object-oriented programmers jump into coding a project with both feet first, without thinking much about the design of the project. This post is sort of a cautionary tale / exercise to get you thinking about what you should consider before you start to write code. The purpose of this article is to show you how using interfaces can make your code both more reliable and more scalable, as well as easier to maintain.

Imagine that we're creating a new end-to-end POS system for a grocery store called BD Market. Let's assume for the time being that you know (or at least you think you know) everything you need to about the domain. So, like any eager programmer who doesn't want to waste his client's time and money you start creating classes - and here's what you have so far:



Notice any problems? If not, then it's a good thing you're reading this. Take another look at the code above and note the following:
  1. Both PerishableItem and NonPerishableItem have the data members Name, SKU, RetailPrice, and UnitPrice in common.
  2. Each implementation of the Scanner class's Scan and CancelScan methods does the exact same thing.
Let's face it: a real-world grocery store scanner can't tell the difference between a perishable food item and a non-perishable one, so why does your Scanner class need to know the difference? The answer is: it doesn't. Furthermore, what will happen if you create a third item class and forget to add a Scan() and CancelScan() method to your Scanner class for that item type? As you can imagine, the situation gets uglier and uglier the more you think about it.

So, what can we do to avoid this mess now, and make it such that adding additional item types in the future won't break our Scanner class? We're going to create an interface called IProduct, that's what:



The IProduct interface defines signatures for the public properties that we want to expose in the classes that implement this interface. We can then refactor our Scanner class so that only one Scan() and one CancelScan() implementation is needed. See the updated code below:



The biggest (and most helpful) difference you can see is that now we only need one implementation of the Scan() and CancelScan() methods in our Scanner class. This has a future benefit as well, because as long as item types we create in the future implement the IProduct interface we do not have to concern ourselves with updating the Scanner class.

I hope that the brief example above has shown you how using interfaces can help you to write more robust code in your object-oriented projects. Please feel free to send any questions my way at brian (at) brian-driscoll (dot) com, or leave a comment below. You can also follow me on Twitter, I'm @driscollwebdev

December 1, 2009

The Problem with Silverlight Right Now

I've been working with Silverlight in its various forms over the last 9 months to develop LOB apps for my employer. I've seen the framework come along from a very lightweight presentation framework to a relatively robust RIA development platform, and I can say that I'm very happy about it and impressed with the Silverlight team for their diligence. Recently, I caught a glimpse of some of the new APIs that will be available in the Silverlight 4 release, and as a business app developer I'm both excited about and impressed with the new features that will be available.

Of course, this excitement is somewhat bittersweet.

As excited as I am about Silverlight 4, I'm really dreading the process of porting my existing Silverlight 3 apps to Silverlight 4, as I'm sure some of the SL3 APIs will no longer work when SL4 is released. I'm also not too thrilled with the fact that I'll have to shell out $$$ to buy VS 2010 and yet another version of Expression Blend just to be able to build SL4 apps and/or port my existing SL3 apps.

TCO is a big issue for businesses right now, and I honestly have to say that Adobe has Microsoft beat in this department. I really like .NET development more than AS3 development for various reasons, but when it comes down to dollars and sense I'm just not sure I can keep paying for the IDE upgrades every time there's a new Silverlight release.