In a recent discussion I was pointing out that in software design I prefer simplicity over coolness, and got the following comment back:
“simple” is not so much more precise than “cool”
This got me thinking. We know a lot about measuring complexity, it may be true that we can’t put an absolute measure on simplicity, but I’m sure we can measure relative simplicity a whole lot more than “coolness”. Let’s give it a shot.
First, we need a measure of simplicity and I’ll suggest to use the number of entities involved. That seems like an obvious and straightforward measure. Something that is constructed out of 5 parts is probably simpler than something that is constructed out of 50. A program with 900 LOC is probably more similar in complexity to a program with 1100 LOC than a program consisting of 50 kLOC. A library exposing 30 classes is probably simpler to use than one exposing 100 classes and a class with 15 methods is probably simpler than one one with 30 methods. There will be exceptions but as a rule of thumb it seems like a good first order approximation.
Next, what dimensions are we going to look at? In software there are different aspects that are important. I’ll propose the following three dimensions:
- Conceptual Simplicity, measuring how many entities we need to understand what the software does,
- Interface Simplicity, measuring how many entities we need to understand how to use the software, and
- Implementation Simplicity, measuring how many entities we need to understand how the software does it.
As an example for these dimensions, let’s consider Smalltalk execution semantics. The conceptual model is quite simple, linked frames that are stored in the heap (a more detailed explanation is here). The interface isn’t quite as simple, there are several classes and many operations (push, pop, temp access, reflection etc) involved. The implementation, in particular when trying to implement the model efficiently, can be highly complex (check out Eliot’s comments on context to stack mapping in Cog).
Now that we’ve got both a value as well as dimensions to look at, let’s apply our measures to see if simplicity can’t be a reasonably precise measure. I’m going to compare MVC and Morphic which are both UI frameworks in Squeak and I’m going to compare the versions in Squeak 4.1 specifically.
In terms of conceptual simplicity, MVC has three entities (Model, View, and Controller) whereas Morphic only has a single entity (Morph). That’s a clear win for Morphic, conceptually, it is simpler than MVC. In terms of interface simplicity there can be no doubt: With 324 Morph classes and 128 Controller+Model+View classes MVC wins hands down in Squeak (the actual ratio is much worse since this counts all of the tools which are subclasses of Model for historical reasons). And again, anyone who has used both will probably agree, that MVC in Squeak has a simpler interface even if it is more complex conceptually. For the implementation of both MVC and Morphic we can use the same values which hands victory to MVC.
(as a side note I’d like to point out that interface and implementation simplicity don’t necessarily go hand in hand. For example, consider memory management. Using memory management functions like malloc() and free() correctly is much more complex than using a garbage collector, but the implementation of a malloc/free allocator is certainly simpler than implementing a garbage collector)
As a result of applying our measures to Morphic and MVC we get a pretty good idea of relative simplicity along various dimensions. It’s not an “exact” measure, and it’s not an “absolute” measure but it is a measure that allows us to compare and contrast software and measure its relative simplicity.
PS. The facade pattern is a great example for explicitly increasing interface simplicity of some subsystem.