Software design


John Ousterhout, the designer of the Tcl scripting language and CS professor teaching a unique software design course at Stanford, wrote a nice book about complexity, modular design, information hiding, comments, etc. Sandy Metz wrote the "Clean Code" book of Ruby programming. It is very practical and can easily be read a few times. Service-oriented design with Ruby is a not completely up to date book but it is a really good discussion of design concerns at a higher level especially of web services. Code Craft is a really entertaining book on programming that touches everything and has many thoughtful ideas about software that are relevant to design (code architecture as pasta).

Agile


Software design is an incremental process where a more ideal, consistent, organized, simple, and optimal design emerges as one gains experience in the system; a good philosophy or approach to allow that to unfold is Agile. With Agile, there is no big design up front of the entire system. An Agile approach might involve some development and then correcting problems with the design (technical debt or actual user-facing functionality) before the next development effort. Don't use Agile as an excuse to be lazy though; do not add unnecessary design technical debt to go faster unless there is a really good reason to. 

Module


A piece of code may be considered as a module, generally a method, function, class, service, system, API. In Ruby, a module is a type of constant that can be used to namespace other constants or as a mixin to extend multiple classes with the same functionality. Anki Books uses a module called Anki Record that is a Ruby library (gem), and all of its code is namespaced inside a Ruby module AnkiRecord. Module is also the superclass of Class in Ruby.

Interface vs implementation


It is important to know the difference between an interface and an implementation in software design and programming. The interface of a module is what the module is specified to do through how it responds to messages to it. The implementation of a module is the internal code of the module that carries out the functionality that the interface provides. In object-oriented programming, a class typically has a set of methods that are public and part of the class's public API and a set of methods that are private and are only callable from inside the class or from inside instances of the class. A web service may have a RESTful API that sends data to other applications and is an example of an interface of a much larger module that might be called a component.

It is more important for a module to have a simple interface than a simple implementation. It will be easier to reuse a module if it has an easy-to-use interface. An easy-to-use interface will also be easier to test and maintain the tests for.

The interface of a module is where dependencies will form on the module and is not the same as the literal public API that callers can invoke. The interface is everything that a dependency can form on which includes information that cannot be understood by the programming language.

API


An API is an application programming interface, and it is a pretty general way to refer to the interface of something related to application programming.

API documentation


A good way to incorporate some ideas of literate programming is API documentation extracted from specially formatted comments in the source code typically right above the methods that they are describing the API of. The source code is the only documentation that will always be present for a program: it should be made as good of documentation as possible. Sometimes a comment above a method explaining what it does is pretty unnecessary, but if you follow the habit then you will probably convey some information for other methods that is really useful later.

Here is an example from the Anki Record gem:

##
# Saves the deck to the collection.anki21 database.
def save
  collection_decks_hash = anki21_database.decks_json
  collection_decks_hash[@id] = to_h
  sql = "update col set decks = ? where id = ?"
  anki21_database.prepare(sql).execute([JSON.generate(collection_decks_hash), anki21_database.collection.id])
end

A comment in Ruby can be started with #. The comment above can be parsed out of the program as documentation of this method. The Rails API Documentation Guidelines explains some very good conventions around this that are used in the development of Ruby on Rails itself. In a development environment where code is being reviewed by other developers before merging into the main branch, code reviews are a good time to ensure that these specially formatted comments are up to date and accurate.

The North Star of software design: minimize complexity.


The most important thing for a piece of code is simplicity. The main objective of software design is minimizing complexity (see Ousterhout). Do not do something in the name of SOLID or any other design principle if the effect is to add more complexity.

Article notes

What is the guiding star of software design?
Previous Next