A UML Sequence diagram can be a great tool for modelling interaction:
UML sequence diagrams model the flow of logic within your system in a visual manner, enabling you both to document and validate your logic, and are commonly used for both analysis and design purposes. Sequence diagrams are the most popular UML artifact for dynamic modeling, which focuses on identifying the behavior within your system.
Yesterday I fancied moving some hand drawn diagrams to mouse drawn form; but instead found myself battling against a somewhat stubborn and forgetful modelling tool. It left me wondering if there might be an easier way to do this; perhaps by separating the concern of model description from layout. A few moments later I had a description language using an F# class and an F# discriminated union:
type Object(name) =
member this.Name = name
type SequenceAction =
| Activate of Object
| Deactivate of Object
| MessageCall of string * Object * Object
| MessageAsync of string * Object * Object
Together the Object and SequenceAction types describe an internal Domain Specific Language (DSL) for Sequence Diagrams.
The following is a simple restaurant sample definition (taken from Wikipedia) using the DSL:
let fred = Object("Fred\r\nPatron")
let bob = Object("Bob\r\nWaiter")
let hank = Object("Hank\r\nCook")
let renee = Object("Renee\r\nCashier")
let objects = [fred;bob;hank;renee]
let actions =
[
MessageCall("order food",fred,bob)
MessageCall("order food",bob,hank)
MessageCall("serve wine",bob,fred)
MessageCall("pickup",hank,bob)
MessageCall("serve food",bob,fred)
MessageCall("pay",fred,renee)
]
Onto the layout, and the .Net Framework has the necessary batteries included to easily do this using either WPF or Silverlight with the:
To get started I used Visual Studio 2010’s WPF XAML designer for prototyping the layout. Then several hours of hacking later I had an F# script (attached) for drawing basic diagrams.
The following was generated using the simple restaurant description above:
The colouring of the objects was achieved by extending the Object to allow arbitary dynamic properties to be set which can later be fed to the control:
type DynamicObject () =
let properties = System.Collections.Specialized.HybridDictionary()
member this.Item
with get (index:string) = properties.[index]
and set (index:string) (value:obj) = properties.[index] <- value
member this.Items =
let keys = seq { for key in properties.Keys do yield key :?> string }
let values = seq { for value in properties.Values do yield value }
Seq.zip keys values
// Define dynamic lookup get and set operators
let (?) (o:DynamicObject) (property:string) =
o.[property]
let (?<-) (o:DynamicObject) (property:string) (value:'a) =
o.[property] <- value
type Object(name) =
inherit DynamicObject()
member this.Name = name
The object’s background colours are set thus:
fred?Background <- Brushes.LightGreen
bob?Background <- Brushes.LightBlue
hank?Background <- Brushes.LightBlue
renee?Background <- Brushes.Pink
Conclusion
Whiteboard and paper are still probably the best tools for modelling sequence diagrams. However the DSL approach does have the advantage of allowing easy insertion of objects and messages without the pain of manual layout (constant erasing and redrawing).
Resources
SequenceDiagram.fsx (11.97 kb)