Since I tend to be lazy, err... I mean efficient, I tend to communicate through pictures.
Whether brainstorming, planning or conveying ideas, I spend a lot of time at the whiteboard. At the end of one such session, a team member will snap a picture of the board and drop it into our corporate wiki.
From there, two things can happen. Either a zealous developer (or architect), will make a beautiful diagram out of the picture (we use omnigraffle which by the way I highly recommend as an alternative for visio). Or the picture will not get touched until someone needs it, and since my white board handwriting is a step down to my already poor handwriting, it will most likely leave the reader guessing as to what exactly we meant then.
Clearly, having a diagram buff is the better of the two options, but doesn't go without drawbacks: it's easy to get side tracked (gradient background anyone?) and waste precious time.
There's an alternative to drawing diagrams by hand. For example graphviz is a great tool to generate renderings of oriented graphs. It uses a domain specific language call 'dot' which looks like this:
digraph G { start -> a0; start -> b0; a1 -> b3; b2 -> a3; a3 -> a0; a3 -> end; b3 -> end; }It supports all sorts of cool features which you can discover here, but again, it's not specific enough and always end up fiddling with fonts, colors etc.
Finally, there's an interesting website I stumbled upon recently called yuml.me. It is essentially a web service to generate UML diagrams. The bummer is that there are 3 diagram types supported so far: activity, class and use case diagrams. Most diagramming I do revolves around components and their interaction. Close but not quite.
Wouldn't it be great if I could express components, interfaces and interactions using domain specific notations too? Maybe something like this:
ICustomer, IXML [Customer] IOrder, IXML [Order] [Customer] persitence -> IPersistence [Persitence] [Customer] orders -> IOrder [Order] [XML] convertCusts -> IXML [Customer] [XML] convertOrders -> IXML [Order]The syntax above language can be defined as follow (using a pseudo-BNF notation):
<identifier> ::= [a-zA-Z]+ <componentid> ::= "[" <identifier> "]" <relationid> ::= <identifier> <interfaceid> ::= <identifier> <expr> ::= [<component> <relation> "->"] <interface> <component> <multiexpr> ::= <expr> [ <exp> "\r\n" ]*Then, translating to Scala using the parser combinators library:
class CDiagram extends JavaTokenParsers { def identifier = "[a-zA-Z]+".r def component = "[" ~> identifier <~ "]" def interface = identifier def relation = identifier def interfaceRefs = repsep(interface, ",") ~ component def relationDef = component ~ relation def expr = opt(relationDef <~ "->") ~ interfaceRefs def multilineExpr = rep(expr) }As you can see, it's pretty close to the BNF notation (complete source).
"[a-zA-Z]+".r : regular expression matching a series of 1 or more letters.
a ~ b: matches a followed by b
a ~> b: matches a followed by b where a is relevant only to the syntax (and discarded at interpretation time)
repsep(a, b): matches a repetition of a separated by b
opt(a): matches a optionally
Very little more magic is all it took to build a converter between the diagram DSL and the dot language. Here's an example of the dot output:
digraph G { node [shape=record]; Customer[label="{<icustomer> ICustomer|<ixml> IXML} | \<\<component\>\>\nCustomer"]; Customer -> Persitence:IPersistence [label="persitence"]; Customer -> Order:IOrder [label="orders"]; Order[label="{<ixml> IXML|<iorder> IOrder} | \<\<component\>\>\nOrder"]; Persitence[label="{<ipersistence> IPersistence} | \<\<component\>\>\nPersitence"]; XML[label="{} | \<\<component\>\>\nXML"]; XML -> Customer:IXML [label="convertCusts"]; XML -> Order:IXML [label="convertOrders"]; }And here's the final rendering:
You can access the full source code for the whole example runnable using SBT on github.