In this installment, we’ll be looking at the problem description for Mars Rover. After becoming more familiar with the problem, we’ll start by identifying the terminology that we should be using when talking about the problem by defining a ubiquitous language. From there, I’ll show you how to break down the problem into various concepts and how to find the relationships between the various pieces. By the end of this post, you should feel comfortable exploring a new domain, understanding the terminology used, and defining relationships.
Congratulations and welcome to the S.P.A.C.E¹ Institute, good to have you aboard! Our big focus for the year is to develop a rover that can navigate the surface of Mars! While the engineers are working on the design and building of the rover, we can focus on building the navigation module and start iterating on its design. With that in mind, here are a couple of assumptions we’re going to make for this version.
- The rover will be traveling on a two-dimensional plane that should be modeled as a coordinate (X, Y)
- The rover is guaranteed to be able to travel in a chosen direction (no worries about obstacles or other landmarks)
Given the above assumptions, here are the business rules that the emulation will need to follow
- When the emulation starts, the rover will always be at (0, 0) and facing North
- There are a series of commands that the rover can receive that can change its location or direction
- When the rover is told to move forward, then it will move one rover unit in the direction it’s facing
- When the rover is told to move backward, then it will move rover unit away from the direction it’s facing
- When the rover is told to turn left, it will rotate 90 degrees to the left, but not change its location
- When the rover is told to turn right, it will rotate 90 degrees to the right, but not change its location
- When the emulation is told to quit, the rover will stop receiving commands
- For the emulation, valid directions include North, East, South, and West
- In order to help troubleshoot failures with the emulation, every time a command is received, both the command received, the rover’s location, and the rover’s orientation should be logged.
¹ Simple Programming Application Checks Expertise
Identifying the Domain
When building software, I want to understand the various business terms that are being used to describe the problem so that when I’m talking to subject matter experts (SMEs), I’m using the same terminology as they are. For those who are familiar with Domain-Driven Design, this practice of using the same terminology is known as defining a ubiquitous language and the goal is to make sure that when someone says Command, then we are all referring to the same concept. If you’ve ever worked in a codebase where something was called one thing, but the business referred to it as something different, then you are familiar with the pain of having to map between the two concepts.
Find The Nouns
When working to define the ubiquitous language, a common approach is to find the nouns that are being used in the description as this can create the foundation of your classes (if following Object-Oriented principles) or your types (if following Functional Programming principles).
Looking over the description again, these nouns stood out to me:
Find The Relationships
Once the nouns have been found, I’ll pivot to finding out how these different concepts are related to each other. One approach to finding these relationships is using “has-a” and “is-a” relationships. At a high level, if two things are related through “has-a”, then those concepts should be composed together. If two concepts have an “is-a” relationship, then I know that the concepts should be interchangeable for one another.
To help identify these relationships, I would work with the SME to understand what each of these concepts means and how they relate to each other. Since it’ll be a bit hard to simulate a conversation, here’s the information that we would learn from our SME.
- A Rover has a Location and an Orientation
- Orientation is the Direction that a Rover is facing
- Location is the coordinates that the Rover is located at
- A Command is something that a Rover receives from the User
- A Direction can be North, East, South, or West
- A Command can be Move Forward, Move Backward, Turn Left, Turn Right, or Quit
With this new understanding, our concepts and relationships would look something like this:
In this post, we explored the problem description for the Mars Rover kata and built up our understanding of the various concepts by exploring the nouns. After finding the nouns, we leveraged “has-a” and “is-a” thinking to come up with a rough idea of how the various concepts related to one another. In the next post, we’ll be focusing on how to model these concepts in code!
- Part 0 – Introduction
- Part 1 – Defining the Problem
- Part 2 – Modeling Concepts
- Part 3 – Intro to Testing
- Part 4 – Implementing Rover Part 1: Move Forward and Move Backward
- Part 5 – Implementing Rover Part 2: Turn Left and Turn Right
- Part 6 – Implementing Rover Part 3: There seems to be a pattern
- Part 7 – Implementing Logger
- Part 8 – Bringing Rover and Logger together
- Part 9 – Wrapping Up and Reflection