Outside-In Development

David Madouros
EarthVectors
Published in
4 min readJun 27, 2019

Hey there. David from EarthVectors here to teach you about one of my favorite techniques for front-end and/or API development — Outside-In Development.

I see many developers start by designing their model/table and work their way outward to the view. In fact, Rails even encourages this by focusing on “resources”. But what if, instead of working inside-out, we tried working outside-in? That’s what this technique is all about.

Advantages of this technique are:

  • Faster Feedback
  • Fewer assumptions
  • Clearer separation of responsibilities
  • Works for any front-end framework
  • It’s fun!

Faster Feedback

Fast feedback is awesome and makes programming easier. It helps maintain sanity by limiting the number of mental balls that you need to juggle. Fast feedback alerts you early and often to mistakes that you make and makes debugging those mistakes a no brainer. Outside-In Development starts with “working” software and a feature spec and ensures that it continues to work as you make small changes that improve the design and move from “working” to working.

Fewer Assumptions

One of the big downsides of inside-out development is that, sometimes, when you finally get to the UI, you find that it’s difficult to mold the UI to the expectations of your model. This can contribute to a difficult to use UX. It can also contribute to compromises made to the model (unless you’re willing to start over and re-think the model based on what you’ve learned at the UI layer). Outside-In Development doesn’t make any assumptions about the model and it has a tendency to create cleaner models and separation of responsibility.

Clearer Separation of Responsibilities

In layered architectures (like web-development), it is important to make boundaries between layers clear — separation of responsibilities. Views should not query the database. Controllers should route requests to the business domain layer. Outside-In Development pushes business logic into the business layer and keeps the View and Controller logic clean and simple.

Works for Any Front-End Framework

In my experience this works with any front-end (and back-end) framework. I used it extensively in Ruby and Rails environments — ERB, HAML, React (with or without Redux), and Backbone. I also used it with Elixir and Phoenix. It also works well with APIs (and is not just for front-end development). I’m not naive enough to claim it works for every situation, but I have yet to find a situation that it can’t help with.

It’s Fun!

Outside-In Development is fun! It makes programming simple and the clean design at the end makes me feel good. It also allows me to conserve brain cycles for things that are truly difficult.

Overview

The idea is relatively simple. I start with hard-coded values in HTML. For example, I hard-code each row in a table. Next, I extract the hard-coded values into a variable of hard-coded values. Then I push the hard-coded values down the stack until I can’t push it down any farther. Finally, I introduce a persistence layer. Throughout the process, I add unit tests where applicable.

Example

I’m writing a simple application for my favorite local used car dealership (DMad Motors). They want a page that lists their inventory of cars.

Caveat: This is a simple application, but it’s enough to demonstrate the technique. I often use a “simple” application to learn new techniques, languages, and tools (sounds like a future blog!).

Step One: Introduce Hard-Coded List

I start by hard-coding a simple list of cars. When doing a list like this I like to start with 2–3 items. One item isn’t a list. And more than three is cruel and unusual punishment. 😉

Note that at this stage it is critical that I write a feature spec to verify the table contents. The feature spec is what makes this technique work and allows me to treat the upcoming changes as a large-scale refactoring.

Step Two: Extract Hard-Coded List into Variable

Next up, I extract the hard-coded values into an Array and introduce a loop for the rows in the table.

I’m choosing to use OpenStruct here. I prefer this to a Hash because it allows me to convert to some more concrete type of object later (e.g., ActiveRecord objects). Some people may prefer Struct for performance, but I know from experience that using OpenStruct is temporary and I find it easier to work with.

Also, I could use a plain variable (i.e., cars) instead of an instance variable (i.e., @cars), but using @cars prepares me for moving this to the controller.

No changes to specs are necessary!

Step Three: Push Data Down a Layer (i.e. from View to Controller)

Then I move the hard-coded list into the controller.

I also introduce a controller spec (yes, I still write controller specs).

Step Four: Introduce Persistence

Finally, there’s nowhere else that I can push the hard-coded list of cars down to and it’s time to introduce some persistence. I create a migration, create a Car model, and update both the controller spec and feature spec to persist Car instances and remove the use of OpenStruct.

Here is the final list:

And the specs:

Summary

This is a simple technique that has a lot of upside for very little cost. It works great when pairing because you and your pair can take turns implementing steps and the process of moving from hard-coded values to persistence ensures that you and your pair are on the same page. Give this a try. I think you’ll like it and I hope you have as much fun using it as I do.

Happy Coding!

Code: https://github.com/dmadouros/dmad_motors

App: https://dmad-motors.herokuapp.com/

--

--