Thursday, January 15, 2009

Data Driven Development (DDD)

In the world of software, methodologies rule. It isn't about the code, it's all about the process. And when it comes to processes, there's a lot to choose from; developers have a habit of over thinking this stuff. So as one, I figured I'd throw in my two cents, too.

Test Driven Development has been a buzz word in the Rails community for a some time. It certainly deserves the credit, too. The peace of mind that comes with a solid test framework is unparalleled. But there's a component of testing that I think is ignored. To write a good test, you need good test data.

You have a couple options when it comes to data:
  1. Fixtures: In Rails, you can use static YAML files to represent the data in your database. Once your migrated, just load the fixtures and you've got some data to work with. The downside here is that to get a lot of data, you have to do a lot of typing. Additionally, as your data becomes more and more complex, it becomes really tough to keep track of the dependencies and associations between objects.
  2. SQL: Aa SQL dump from another machine or production is a great fast way to get tons of data, but is incredibly fragile. As your database changes, the migrations and schema may deviate machine to machine, and it only takes one change to invalidate an entire SQL dump. They're a pain to work with as most text editors crash on such large files.
Recently, however, another option has become available: generate it! I was really inspired after watching the Populator Railscast by Ryan Bates, in which he demonstrates using Ruby to spin up a few hundred database rows in a few minutes. With simple models, it's a totally painless process. So what happens when you outgrow the out of the box Rails application?

Well, I say you stay disciplined. When you embrace TDD, it becomes weird not to write the test cases first. Same thing here, for what I'm calling Data Driven Development. Write the tests, migration, model, and a data generator in one process. Change your model? Change the data, and change the test. Every model should have tests. Every model should have a data generator.

Using the populator and faker gems was a great way to get started. In a few places you have to do some work directly with ActiveRecord, when relationships become complicated, but it's relatively painless. I wrote the following method that I call at the beginning of each generator to deal with dependency issues that helped me quite a bit:

# Given a set of class names, will require objects of those types to have been populated
# Usage: depends_on(User, Post, Comment)
def depends_on(*args)
  raise "Depends on #{args.map{ |a| a.name.pluralize }.to_sentence.downcase} to populate data." if args.any? { |a| a.count.zero? }
  args.each { |a| eval "@#{a.name.underscore.pluralize} = #{a}.all" }
end

This not only helped declaratively define my dependencies, but also sets up whatever instance variables (i.e. @users) to help you out with the generator.

As far as testing goes, factories come in really handy. It's just like using a generator, but knowing that the output will be the same each time. For my tests I completely rely on factory_girl. Not only can they run much faster as many tests don't even need to hit the database, they allow each test to declaratively set up exactly the conditions you need.

Ultimately, the approach gives you more peace of mind. Loose your database? No problem: migrate, then generate. Need more data? Generate millions of fake records while you grab a cup of coffee. Good deal.

Tuesday, December 23, 2008

In-n-Out Burger: Consistency, Animal Style

I recently took a trip out to California and had my first dinning experience with In-n-Out Burger. I really reveled in the experience, because they've really nailed, what in my mind, makes a great product.

Immediately In-n-Out Burger's menu jumped out at me. In my day to day operations I'm often tasked with conveying information quickly. The web is my domain, but regardless of medium, the most easy to convey information is also simple information. I've commented before on how Apple has been successful following this mantra. So when I walked into In-and-Out, expecting to become quickly stressed with an overload of options, sizes, and extras, I was pleasantly surprised to find this instead:


No tricks here. A simple set of options, listed by price. A whopping 34 possible menu options by my count. Which seems pretty easy when I compare it to any other fast food places - yeah, that's right, no salads here. Even the option I found most delicious - "animal style", is unlisted on the menu. Talk about restraint and compromise.

So, we sit down to eat and I'm anxious. I've heard good things, and am happy thus far, but just because they have a simple menu, doesn't say anything about the food. Fresh ingredients: crunchy lettuce, a thick tomato wedge you can actually sink your teeth into, tasty sauce, and real beef, all on a toasted buttery bun. French fries, cut from whole potatoes right before your eyes. Delicious.

First experience was a huge success. But what was really inspiring were the subsequent visits (I tallied 6 charges on my credit card statement after the trip). In-and-Out Burger, beyond making delicious burgers, wins because they're consistent. The deliver the same experience every meal at every location. The menus, burgers, fries, outfits, tile, floor-plan, receipts, toilet paper - all, exactly the same from store to store. It's like someone came through with a Chinook and just airdropped them into a lot. This serves the customers, while most not as detail obsessed as I, in making the experience more familiar and completely reliable. And it serves the franchise; just think how much money was saved not having to re-hash every detail.

I was really impressed, and will think back to my experiences there while working in my domain. But first... something to eat. consistentency

Wednesday, November 19, 2008

CSS Tricks (2 of 2): Using Rails to Manage Styles

For the second half of my CSS "tips n' tricks" tutorial, I'd like to take some time and discuss how Rails can help manage stylesheets. As you start out any Rails application, there are some huge conventions you follow within the 'app' folder. I think these conventions make it much easier for developers to find, maintain and create code. But when it comes to stylesheets I find there to be a notable absence of these conventions.

My web applications have, in the past, began as one stylesheet called "default.css" or "application.css" and placed in the stylesheets folder. I'd try and arrange similar styles in similar places, and use comments to help organize it. Pretty soon I had a 800 line CSS file on my hands and was hunting to find styles on various pages. I knew there had to be a better way, and thanks to Rails and some conventions I've started following, I think I've got a decent system. It involves 3 basic components: using controllers and actions as CSS selectors; many shorter CSS files; and Rails stylesheet caching.

1. Controllers and actions as CSS selectors: Depending on the application, you'll be using some kind of layout in the views/layouts. I usually stick with something like views/layouts/application.html.erb early on in the game. The first thing I do is make whatever div I have wrapping my main content area adopt the current controller and action names as CSS classes:

This means that now in any stylesheet I have full control over what gets rendered and no style can step on the feet of another. For example:
  • div#wrapper div.users.index { /* insert index specific styles here */ }
  • div#wrapper div.users { /* insert common styles for all user actions here */ }
  • div#wrapper { /* insert styles common to all controllers here */ }
The key is to religiously obey these prefixes. In Part 1 of this CSS series I talked about being as specific as possible with CSS selectors, and this is why. If you're not, you'll spend hours trying to figure out why something is rendering a certain way only to find that it's inheriting something entirely irrelevant. So once you have that sorted you can then make...

2. Many shorter CSS files: So if you have a controller like UsersController, you'll have a folder, views/users. Within that you'll have files that respond to each action. Do the same thing for your styles. Create a folder public/stylesheets/users and create a stylesheet for each view that warrants its own styles. To follow the example above, you can now take any CSS that starts with div#wrapper div.users.index, and place it in public/stylesheets/users/index.css. Same thing for every other action, and partials too... hell, I even prefix those files with an underscore. I try and make the files stylesheets folder mirror the views.

You have to get a little more creative when it comes to common styles (those that span multiple controllers or actions). For styles spanning multiple actions, simply create a common.css inside the controllers folder. For styles that span multiple controllers, chances are that a layout exists for that part of the application. For example navigation that may be common to administrations would go in public/stylesheets/admin.css to correspond to app/views/layouts/admin.html.erb. 

This process, actually works really well with javascripts too. It may seem ridiculous to include so many stylesheets into the final HTML that gets rendered, but fortunately you can send it all down as one.

3. Rails stylesheet caching: This is where it all comes together. With one simple command we can get the web server to concatenate all these files into one sheet that gets sent to the client:
In some cases I'll just bundle every CSS file I create into one sheet, or if the application is a bit more stratified you can create sets of caches. Usually the structure of your layouts will determine how you set these up.

This set up means you as a developer don't have to loose time trying to find the styles that correspond to their respective view HTML, can save time when debugging by eliminating accidental style inheritance, and still send one file to the client. Enjoy.

Thursday, September 18, 2008

CSS Tricks (1 of 2): First, Get Down with the OOP

Introduction
I recently stumbled upon an interesting web design blog that featured an article about some CSS "essentials" and commonly used CSS code snippets. I read it with a great amount of interest and found that I had a few tricks and tips up my sleeve that I'd like to contribute as well. So this is the first in a two part post about how to improve your CSS and make the design process more fun and less stressful.
I immediately found that a lot of my tricks don't actually have anything to do with visual design or CSS at all, but more about structure and design patterns. Funny, how that sort of thing happens when you learn how to code first. I've found that you can bring a lot of the organization and philosophies that come from structuring application code right into the presentation layer. Here's what I've learned...


Embrace a Convention Through and Through
Seriously, if you're not using some kind of structure when it comes to building an application, you should probably go read some other blog. I'm somewhat infatuated with the MVC pattern these days, but for the sake of what we're doing here I don't know that it matters.
The idea is that you have various objects or models throughout your code. You may have some Users, Products, or Messages. The problem is that by the time they get to the view part of your application, their meaning has been diluted. Distill it.
You have a fairly common set of tasks for any object: List (index), view (show), create (new), update (edit), and delete (destroy). Almost all of those require a presentation of some kind, with the exception of delete, usually. There's an obvious Ruby slant in these snippets, but I think you can handle it:
Index:
View:
Create / Update:
With this kind of structure, your CSS stays organized and follows much of the meaning defined by the business objects themselves. I would encourage designers to try and think as much like this as possible. Instead of reinventing names for classes and ID's look to the structure of the application code first and let it drive the front end.


Don't Over Refactor CSS
Just like with code, your CSS can become overly abstract. If you need to style a single element on a single page, start with inline styles. An ASP.NET developer once told me, "never use inline styles - everything needs to have corresponding class or ID." That attitude is part of what's contributed to my career switch to Ruby on Rails. Don't create a class for it until you see commonalities start to evolve.
An example: You may find that you're putting a paragraph that needs a particularly attention grabbing look. Start with a paragraph and set its style attribute. Make it look just the way you need to for that one instance. As you continue to work on the site you may find that you want a link to actually look similar to that paragraph, maybe they're both a specific shade of red. Go back to that paragraph, remove the color property, and create a class called .red, which you can now apply to both. The growth is now organic and maintainable.


Tame the CSS File
Whether it be in a Controller, Stored Procedure, or CSS, it's not OK for files to just grow to thousands of lines without taking a step back and saying, "woah", what just happened here? To avoid this little conundrum I like to use the CSS @import function. Group common styles together and import them when the page renders to make the developers lives easier.
I know what you're going to say. There's a significant performance hit for this, and I hear you. It's not OK to go to production using @import, because each file will require another HTTP request, which isn't cool. But, if you're doing anything serious, you'll have a deployment process and you should let that piece of the puzzle take care of grabbing the CSS and compiling it all together into one file.


#Be #as .Specific .as:Possible
It's very easy to be lazy with CSS and end up with thousands of styles that conflict with one another. You also may not realize that there is common styling between elements that could be "refactored."
Let your CSS selectors follow the DOM as closely as possible. If you look back to the index example above you could easily just style off of .user, but that's exactly the type of laziness I'm talking about. Use #users .user instead. It will make life easier in the long run, and isn't that what development is all about?


Conclusion and What's to Come...
The approaches here are pretty high level, but in the next part of this post (Part 2, for those you playing at home), I'll talk with about more concrete examples on a line-by-line basis.

Sunday, September 7, 2008

People and Process

Over the last couple of days I've come to an astounding realization. While I had always considered that the culture of a company - its people and practices - made a difference in its day-to-day operations, the scope had eluded me.



This month's issue of Inc. magazine featured an article about a law firm that is changing the way they do business. After noticing depreciating morale, and low outcome they revolutionized the way their office was run by implementing a strategy known as ROWE, a results-only work environment. Standing up against the "tried and true" 8-5, more hours is better, work hard play hard, meeting frenzied corporate culture, this approach seems insane. Forget about classic work culture for a moment and think just about how to get work done effectively. It might actually make sense to work when it's most convenient for you, balance your personal affairs the way you need to, and set your own deadlines. These are all practices that ROWE embodies, even down to the receptionists. It's the results that matter, not the logistics. Of course, it requires some discipline, but wait a second, do you want to employee people that need a schedule to be productive? That doesn't really jive with having "passionate" employees, does it?

37Signals, of course, has tooted this horn for quite some time now. 4 day weeks, they say, has boosted productivity, catapulted morale skyward, and absolutely energized their company. It's all about working "fresh;" maximizing your personal time to explore new opportunities and expand the mind to bring to work your absolute best.

Of course, Google, is the ultimate example of this.

What is interesting to me is that none of these approaches is domain specific. A law firm, a software company, and a search engine, all practicing new approaches to corporate policy, all claiming increased productivity and performance. It doesn't really matter what you do, but how you do it - the process behind it.



When I was working at William Lawrence Camp as a counselor, I remember being a part of the tradition of "Beach Day." It's a pretty grueling process for the staff, but the kids really enjoy pilling into buses, driving an hour and a half to the beach, and pilling on sun screen. When we get back, we always close the day out with a barbeque. I've always enjoyed grilling, and when we got back from one such trip, I jumped at the opportunity to help out on the grill. The head counselor, who was keeping an eye on things walked over to me and said, very simply, "Andy, you're doing a great job, and thanks a lot for your help." Buried in a billow of smoke and charcoal, I thanked him and noticed that instantly I wanted to help out even more. The urge was overwhelming.

It's the amazing power of positive reinforcement. I think the tendency is to think that these philosophies don't really apply in the "real world." After all, we're all adults here, and we have to put on our work clothes and just "get the job done." That's what it's called, right? "Work." So many "work" cultures are just that: a place where it's not about being a part of a team but just producing, however that needs to happen.



I'm very fortunate to be involved in the career of my choice, something that I am tremendously passionate about, and I can understand that a lot of people, from a lot of walks of life, don't share similar circumstances, but I doubt that it would matter very much. My point is that what you do, is far less important to how you do it and who you do it with.

The image from Iwo Jima, for me, conjures up the emotion of the later. That tremendous feeling of camaraderie. It's the root of patriotism, and could be, arguably, the root of U.S.A's strength. Imagine a business running on that fuel.

And as for how, I think back to companies like the ones I mentioned above. It's a common theme of bringing employees closer together, while renouncing micromanagement and promoting quality results. Within my field of software development, "agile" processes come to mind, and I'm sure each industry has its own parallel.

This is of course more a science than I may be suggesting, but can't it be measured through emotion? Think again about the feeling that photo conjures. Do you feel like that at work and don't you think you'd get a lot more done if you did?


Tuesday, September 2, 2008

Bravo 37Signals for Phasing out IE 6!

It's been a long time coming...

Too much time has gone by with developers forced to limit their imaginations, creativity and ability to support the "rusty weight of IE 6." But most websites have been afraid to stick their neck out.

So, kudos to you, 37Signals, for doing your part to rid the world of IE6.

Friday, August 1, 2008

Enigmo: A Shower of Entropy

Since I got my iPhone 3G, I've downloaded, that is paid, for exactly 3 games. The best - by a long shot - is Enigmo, from Pangea Software. For those of you who don't know it, it's basically a puzzle game where you have a certain set of tools on each level that you need to use to somehow route a bunch of droplets of liquid from point A to point B. Sounds lame, right? Maybe this will clear things up:


Not so lame anymore, huh? Yeah, that's what I thought.

Anyway, this game, besides just blatantly robbing my time, has actually spoken to me on a deeper level (think wading pool). For those of you who may know me, I'm a bit of a perfectionist. I find myself constantly balancing my idealism against productivity and efficiency. Enigmo helps me practice this. You're trying to get all of these little droplets over to one place, but soon realize that things are just a bit more chaotic than you accounted for. In almost all the levels, much to my dismay, you just can't get every droplet into the pot. It's all about getting "good enough."

And that's OK! Because there's a countdown racing to zero, and the goal isn't to get all the droplets into the pots, but rather to get as many points as possible by finishing quickly. And even then, you only need to fill fast enough for them not to evaporate. The best way to get big points: just do it. It doesn't have to be beautiful or ideal; there's no "grand scheme" to the game, and there's definitely more than one solution.

So if you, like me, suffer from "entrophobia", pick up this game asap and start embracing the insanity.