I’m on my way back home after a great Ruby Hoedown in Nashville, where I gave a talk called “Fractal Design.” This is the second(ish) time I’ve given this talk, having previewed it in a very conversational format at the Charlotte Ruby Users’ Group a month or so ago – but I’m starting to think it’s better suited for a blog post (or series of, at least), so: this.
The idea behind the talk is that, just as fractals are the immensely complex, impressive, and emergent results of the repeated application of a simple set of rules at different levels of magnification, so to might we produce complex and impressive software by repeatedly applying a simple set of principles and practices at different levels of code.
The Sierpinski Triangle
So most people have probably seen the Sierpinski Triangle at some point. Heck, I bet more of them have been idly doodled in middle school math notebooks than were ever generated by practicing mathematicians.
The basic idea is that you start with an equilateral triangle.
You then remove the triangle formed by connecting the midpoints of each side, leaving you with three new triangles:
Next, you do the same thing to each of these three triangles – remove smaller triangles from the center of each:
And on and on, as many times as you like.
What you end up with is impossibly intricate, and can be manipulated in surprising ways. When conceived of in three dimensions, you end up with a structure that has an infinite surface area and no volume at all! (a pyramidal Menger sponge)
OK, so software isn’t exactly analogous to pure geometric space. Nevertheless, we do have distinct levels of magnification:
methods → classes → libraries → applications → ecosystems
We also have a large array of software design principles and practices, each of which is usually couched in the language of one of these levels (or at most, two adjacent levels). The SOLID principles, XP’s practices, the law of Demeter, design patterns – what would happen if we tried applying them across our entire body of software, instead of just when designing a library’s API, a user interface, or a single method?
So that’s the question. In future posts I’ll tackle this question with specific principles, and hopefully we’ll find something interesting.