# Puzzle Driven Development

Source: https://www.yegor256.com/2010/03/04/pdd.html

{% badge https://avatars2.githubusercontent.com/u/24456188 L https://www.0pdd.com %}

PDD, or Puzzle Driven Development, is a method used to break down programming
tasks into smaller ones and enable their implementation in parallel. The PDD
method is used widely in [XDSD](https://www.xdsd.org) methodology. The method is pending a USPTO patent
(application no. [12/840,306](https://www.google.com/patents/US20120023476)).


Let's review the method with an example. Say, for instance, you are a programmer
and have been tasked to design and implement a Java class. This is the formal
task description: "class `DBWriter` has to extend `java.io.Writer` abstract
class and save all incoming data into the database."

{% youtube nsYGC2aUwfQ %}

You have one hour to implement this task. It is obvious to you that one hour is
not enough because the problem is much bigger and requires more work than the
slotted time allows. Additionally, there are a numerous unknowns:

 * What information do we need to save, and in what format?
 * What is the DB schema? Is it an SQL or NoSQL database?
 * How to connect to the DB? JDBC? JPA? DAO?
 * How to handle exceptions?

Let's keep all these unknowns in mind as we try to solve the problem on the
highest level of abstraction. Of course, we start with a test:

```java
import org.junit.*;
import static org.mockito.Mockito.*;
public class DBWriterTest {
  @Test
  void testSavesDataIntoDatabase() throws Exception {
    DataBridge mapper = mock(DataBridge.class);
    Writer writer = new DBWriter(mapper);
    try {
      writer.write("hello, world!");
    } finally {
      writer.close();
    }
    verify(mapper).insert("hello, world!");
  }
}
```

In the above test, we define the expected behavior of the class. The test fails to compile because there are two missing classes: `DataBridge` and `DBWriter`. Let's implement the bridge first:

```java
import java.io.IOException;
public interface DataBridge {
  void insert(String text) throws IOException;
}
```

Next, the writer itself:

```java
import java.io.IOException;
import java.io.Writer;
import java.utils.Arrays;
public class DBWriter implements Writer {
  private DataBridge bridge;
  public DBWriter(DataBridge brdg) {
    this.bridge = brdg;
  }
  @Override
  void flush() throws IOException {
  }
  @Override
  void close() throws IOException {
  }
  @Override
  void write(char[] cbuf, int off, int len) throws IOException {
    String data = new String(Arrays.copyOfRange(cbuf, off, off + len));
    this.bridge.insert(data);
  }
}
```

Using the above code, we solve the problem. In the example, we successfully
designed, implemented and tested the required `DBWriter` class. Subsequently,
the class can now immediately can be used "as is" by other classes.

{% youtube LmSaC_OjIbQ %}

Of course, the implementation is not finished, since we are not writing anything
to the database. Furthermore, we still  aren't answering the majority of
questions asked in the sample scenario. For instance, we still don't know
exactly how the database needs to be connected, its type (SQL or NoSQL,) the
correct data format and so on. However, we've already made a number of important
architectural assumptions, which allowed us to implement the class and make it
usable by other classes.

Now it's time to identify the unknowns in our code and mark them with puzzles.
Every puzzle is a request for refinement. We want to ask someone else to help us
refine and correct our assumptions. Here is the first puzzle we need to add:

```java
public interface DataBridge {
  /**
   * @todo #123 I assumed that a simple insert() method will be
   *  enough to insert data into the database. Maybe it's
   *  not true, and some sort of transaction support may be
   *  required. We should implement this interface and create
   *  an integration test with a database.
   */
  void insert(String text) throws IOException;
}
```

The puzzle has three elements: `todo` tag, `#123` locator and a comment.
Locator displays the following: "The puzzle was created while working with
ticket #123."

Let's add one more puzzle:

```java
void write(char[] cbuf, int off, int len) throws IOException {
  // @todo #123 I assumed that the data should be sent to the database
  //  as its received by the writer. Maybe this assumption
  //  is wrong and we should aggregate data into blocks/chunks
  //  and then send them to the data bridge.
  String data = new String(Arrays.copyOfRange(cbuf, off, off + len));
  this.bridge.insert(data);
}
```

This puzzle indicates one of our concerns because we are not sure that the
architectural decision is right. Actually, the design is very primitive at the
moment and very likely to be incorrect. To refine it and refactor, we require
more information from the task specifier.

The task is finished. Now, you can reintegrate your branch into `master` and
return the ticket to whoever assigned it to you. His task now is to find other
people who will be able to resolve the puzzles we just created.

Every puzzle created now will produce other puzzles, which will be resolved by
other people. Consequently, our simple one-hour task can potentially generate
hundreds of other tasks, which may take days or even years to complete.
Nevertheless, your goal of working with your specific task is to finish it as
soon as possible and reintegrate your branch into `master`.

## Best Practices

There are a few simple rules that help you to place puzzles correctly.

First, you should put your `todo` annotations at the point where your code hits
a stub. For example, in a unit test. You're implementing a test and it fails
because the class has not yet been implemented. You skip the test with the
`@Ignore` annotation and add a `todo` puzzle to its JavaDoc.

{% youtube pvZDcytPU3w %}

Second, your puzzle should remain as near as possible to the code element that
is hitting the stub. Say that you have a unit test that has three test methods.
All of them fail now because the class has not been implemented. The best
approach would be to ignore every one of them and create three (!) puzzles. Each
one of the puzzles should explain what you expect from the class and how it
should be implemented.

Third, be as descriptive as possible. Your puzzle will soon be a task definition
for someone else. So, explain clearly what you expect the next person to
implement, how to do it, which documentation to use and so on and so forth.
There should be enough information present that the next person assigned to the
puzzles is able to implement your required classes without additional input from
you!

BTW, puzzle collection process can be automated by means of our
[PDD Ruby gem](https://github.com/yegor256/pdd) and
[0pdd.com]({% pst 2017/apr/2017-04-05-pdd-in-action %}) hosted service.
