Essay 48 Separate Robot Work from Human Work

If code makes a dream candidate for a junior developer, then we ought to get it to work right away. The faster we can push tedious, algorithmic work off our plates—the kind of work perfectly suited to code—the quicker we can focus on the more interesting problems.

We have all had those moments of déjà-vu programming: pasting code from one project into another or wasting hours writing functionality we know we’ve written somewhere else before. On days that we’re not inspired to rethink the entire process, we get through it and move on to the next task.

images/andertoons_6152.jpg

This kind of passive mentality has to stop. Instead of repeating even a small scripting task, we can write a program to do that work for us. A programmer’s time is far too valuable to be wasted on repetitive tasks. When I co-founded We Are Mammoth in 2006, this is what I had rolling through my mind.

In the beginning, we built Flash applications with a .NET back end using C#. A few months into our business, I began smelling repeatable work: work that we were doing in the same mechanical way each time. Having seen the process for a few iterations, I started to separate the tedious yet algorithmic elements from the custom work that applied to each project we built. They separated like oil in water.

Every application we built followed a common set of conventions. After designing the database, we would write a series of stored procedures in SQL and then create objects in C# that would pull data from these stored procedures into their own properties. After that, we’d build a series of web hooks that would interface with another set of classes in ActionScript. Only then could we start developing any functionality on the Flash side. This hunk of development was tedious, banal stuff better fit for a robot than a human.

images/andertoons_5518.jpg

There were two components of an application that weren’t algorithmic. The first was the database schema. We worked on applications for car companies, bed manufacturers, brokerage firms, software distributors, and fast-food chains. Their databases were custom-tailored to solving their own unique business problems. Second, we couldn’t trivialize the user interface. They were custom-designed for each client. That’s what we wanted to focus most of our time on.

This is when we stopped and took the time to roll our own code generator.

To better explain how we extracted the repeatable bits of our process, imagine building a blog from scratch. We’ll start at the very bottom, with the database. The data model might contain three tables that look like this:

  • Posts(ID, Title, CreateDate, Body, AuthorID)

  • Authors(ID, FirstName, LastName)

  • Comments(ID, Comment, Email, CreateDate, PostID)

If you’re familiar with object-relational database modeling, this model is a fairly straightforward one. Posts has a title, a body, a create date, and a relationship to one Author via the foreign key AuthorID. AuthorID points to a record in the Author table by matching on the author’s ID column. The Comments table contains a comment, an email address, a create date, and a related originating Post, via the foreign key PostID. The PostID keys into the table Post by matching on the post’s ID column.

Uncovering Repeatable Coding Tasks

In the early days of our business, we would start building an app by writing stored procedures to insert (i.e., create), read, update, and delete a record for each table in our data model. These “CRUD” methods were the base procedures for manipulating records in our database. Here’s what I’d type to build an insert procedure for the Posts table:

 
CREATE​ PROCEDURE CreatePost (
 
@Title NVARCHAR(255),
 
@Body NTEXT,
 
@CreateDate ​DATETIME​,
 
@AuthorID ​INT​)
 
AS
 
INSERT​ ​INTO​ Post ​VALUES​ (
 
@Title,
 
@Body,
 
@CreateDate,
 
@AuthorID)

In the CreatePost procedure, we would simply take all the fields in the Posts table, besides the primary key (in this case, the ID field), and build a SQL INSERT statement with corresponding input parameters.

Because we can describe exactly how to write this kind of method by introspecting our database model, a program can generate any generic creation method. The same process described earlier could be repeated for the Authors and Comments tables.

We can apply this same kind of routine for generic UPDATE, READ, and DELETE procedures. For instance, to write an update procedure, we can take all the fields in a table and build a SQL UPDATE statement using the primary key fields (in our case, ID) as filters in the WHERE clause. Here is what the UpdatePost procedure would look like if we followed that prescription:

 
CREATE​ PROCEDURE UpdatePost (
 
@ID ​INT​,
 
@Title NVARCHAR(255),
 
@Body NTEXT,
 
@CreateDate ​DATETIME​,
 
@AuthorID ​INT​)
 
AS
 
UPDATE​ Post
 
SET
 
Title = @Title,
 
Body = @Body,
 
CreateDate = @CreateDate,
 
AuthorID = @AuthorID
 
WHERE
 
ID = @ID

What other types of queries can we generate? For one, we can extrapolate selection queries based on the relationships between each of these tables. For instance, a post has an author. So, we could write a SELECT stored procedure to get all the blog posts by a specific author’s ID. Let’s call it GetAllPostsByAuthorID. We could similarly write a procedure to get all comments by a post’s ID (GetAllCommentsByPostID).

 
CREATE​ PROCEDURE GetAllPostsByAuthorID(@ID ​INT​)
 
AS
 
SELECT​ * ​FROM​ Posts ​WHERE​ AuthorID = @ID
 
 
CREATE​ PROCEDURE GetAllCommentsByPostID(@ID ​INT​)
 
AS
 
SELECT​ * ​FROM​ Comments ​WHERE​ PostID = @ID

Another formulaic pattern emerges in our stored procedures. For any foreign key [Y] in a table [X], we could write a stored procedure of the following form: GetAll[X]By[Y]ID.

Let’s take it one step further. We might want to load records by filtering on a specific field. For instance, we’ll need to get posts for a given day:

GetAllPostsWhereCreateDateEquals(CreateDateParam)

or authors by their last name:

GetAllAuthorsWhereLastNameEquals(LastNameParam)

Another formula emerges. For any filterable field [Z] in a table [X], given a parameter [P] we could write a stored procedure of the form GetAll[X]Where[Z]Equals([P]).

We can find similar tedious yet algorithmic processes when creating a C# data access layer, an API that our Flash layer would be able to consume, and the ActionScript layer itself. All that baseline underlying plumbing is fit work for the fictitious Craigslist job seeker we saw in the previous essay. Or, more realistically, we can write smart programs to do the job for us.

All of this would be a lot of work to do every time we started a new project. But by figuring out the formula for this type of work, we can relegate the execution of this type of work to...the robots.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.116.51.117