Welcome to this Mars Rover series where we're going to practice the followings:

Monolithic Repositories (MonoRepo)

Command / Query Responsibility Segregation (CQRS)

Event Sourcing (ES)

Test Driven Development (TDD)

In this introductory article, we're simply going to describe our Mars Rover specifications.

Note: This programming exercise originally comes from Dallas Hack Club, which is now unfortunately down. This Mars Rover kata has been adapted for the needs of this series.

But first, let's have a quick reminder on what the practices mentioned above are.

Monolithic Repositories

A MonoRepo is a single versioning repository containing many packages that would otherwise be versioned in their own repositories.

With it, everything can be found in one place, which makes it easy to:

navigate

manage dependencies

set up

run tests

However it also brings the following disadvantages:

no hard separation between packages (thigh coupling is possible)

limited regarding scaling (disk space, bandwidth)

no finely grain permission management (a user has access to everything or nothing)

MonoRepos make sense for projects that would be packaged / released together (although it makes it possible to package / release them independently).

Command / Query Responsibility Segregation

CQRS is about separating "write" logic from "read" logic, and it can be applied on many levels, for example:

have a read-only microservice and a separate write microservice

have endpoints / tasks that are either write or read only

separate your models in two (again, read-only and write-only)

It's important to note that CQRS can also be applied partially in the same project: use it only when it makes sense.

Event Sourcing

With ES, every significant action is recorded as an "event". Keeping track of those events provides the following advantages:

replay them to recreate the state of an application at a given time (undo, redo, synchronization)

analyse how the latest state came to be (compare two versions or find who did what and when)

Just like with CQRS, it's important to note that ES can also be applied partially inside a project : use it only when it makes sense.

ES is often associated to CQRS, but they can be used separately.

Test Driven Development

TDD can be summed up in the following steps when developing:

create a test then write just enough code to make the test pass (quick and dirty, or "make it work") then refactor the code (clean, or "make it right")

Writing the test before the code forces us to think about how we'd like the future code to be used. It's like writing specifications, but with 3 purposes: design, documentation and automated regression checking.

This discipline makes it easy to have a high code coverage (although rigour still needs to be applied: we need to test all the happy paths and all the unhappy ones).

Specifications

The purpose of this series is to create the software of a Mars Rover, according to the following specifications.

Mars Rovers need first to be landed at a given position. A position is composed of coordinates ( x and y , which are both integers) and an orientation (a string being one of north , east , west or south ).

It is then possible to drive them, using instructions such as move_forward (keeps orientation, but moves along the x or y axis) or turn_left / turn_right (keeps the same coordinates, but changes the orientation).

From time to time, they'll be requested to give their current location (again, x and y coordinates and the orientation).

For example, a rover can be landed at 23 , 42 , north and then can be instructed to move forward twice, then to turn left, then to move forward once. When requested to, it should provide this location: 22 , 44 , west .

Identifying use cases

From the above specifications, we can identify at least three use cases:

Landing a Rover on Mars Driving the rover Requesting its location

What's next

In the next article we'll initialize the project by creating the MonoRepo and its first package: navigation .