Encapsulation and horses

2 min readPublished November 16, 2019Updated May 02, 2022

This post is the eighth of a series adapted from my conference talk, Fun, Friendly Computer Science. Links to other posts in the series can be found at the end of this post.

Did you know that a horse has 4 main gaits? A horse can walk, trot, canter, and gallop. Walking is characterized by a slow, 4-beat pace. Trotting is a bit quicker 2-beat gait. Canter is even faster with a 3-beat gait. And galloping is a horse’s fastest pace characterized by a 4-beat gait.

If you were playing a programming game where you had to move a horse across the screen, would you want to be required to know about the different gaits that a horse uses at different speeds? And what order to move the legs in to achieve those gaits and those speeds? Probably not.

The first principle of object-oriented programming is encapsulation. Encapsulation is when you "hide" an object's state from other objects. You create a public interface (a method or property) for other objects to interact with your object and mutate its state. When you encapsulate an object, you don’t allow any other object to mutate your object’s state directly. The only interaction is through the interface you defined.

In the horse example, you would create a horse object with methods for walk, trot, canter, and gallop that handles animating the horse’s legs to match the desired gait and speed. This way the user doesn't need to manually mutate the state of the horse's legs in the correct order.

For example, an extremely simple version of your canter method might look something like this

canter(steps) {
  let time = 0;
  let distanceTraveled = 0;

  for (let i = 0; i < steps; i++) {
    this[backLeftLegPosition] = LegPosition.UP;
    this[backLeftLegPosition] = LegPosition.DOWN;

    this[backRightLegPosition] = LegPosition.UP;
    this[frontLeftLegPosition] = LegPosition.UP;
    this[backRightLegPosition] = LegPosition.DOWN;
    this[frontLeftLegPosition] = LegPosition.DOWN;

    this[frontRightLegPosition] = LegPosition.UP;
    this[frontRightLegPosition] = LegPosition.DOWN;

    time += 0.27; // 3.667 steps / second
    distanceTraveled += 6; // 22 ft / second
  }

  return { steps, time, distanceTraveled };
}

And then other objects or your user would make a horse canter with the following code

const GiddyUp = new Horse();
const steps = // read from input;
GiddyUp.canter(steps);

Well-Rounded Dev

Liked this post? Subscribe to receive semi-regular thoughts by email.

    I won't send you spam. Unsubscribe at any time.