I appreciate examples which are more than “hello world” code, but which are still easily digestable - especially when they illustrate solid, basic design practices.

I have been reading A Philosophy of Software Design by John Ousterhout (see here). In chapter 6 section 2, an example is given for a specific API design question: How to design text editor behaviors for features such as “backspace” and “delete”?

The author describes an initial (naive) approach, in which each feature gets its own interface:

1
2
3
void backspace(Cursor cursor);

void delete(Cursor cursor);

Each implementation has its own dedicated logic to handle each required function.

And so on - for example, deleting a section of selected text:

1
void deleteSelection(Selection selection);

The author points out how the methods of the text class closely correspond to the features visible to users. This specialization provides little benefit, and results in what Ousterhout refers to as an overall “shallow interface”.

He then discusses a much more general-purpose approach:

1
2
3
4
5
void insert(Position position, String newText);

void delete(Position start, Position end);

Position changePosition(Position startPosition, int numChars);

And then, features can be implemented on top of these interfaces:

1
2
3
4
5
// the delete key:
text.delete(cursor, text.changePosition(cursor, 1));

// the backspace key:
text.delete(text.changePosition(cursor -1), cursor);

These interfaces are longer, but more obvious. And there is less code overall…

And what about search/replace? That can be implemented as follows:

1
Position findNext(Position start, String string);

It’s a simple lesson, but one which is so easy to forget (I confess). I appreciate the reminder, using such a clear and simple (but not trivial) example. This one will stick with me.