Skip to content

Instantly share code, notes, and snippets.

@dirx
Last active April 7, 2021 18:13
Show Gist options
  • Save dirx/426e3099f07658965ee762cc70eba3cf to your computer and use it in GitHub Desktop.
Save dirx/426e3099f07658965ee762cc70eba3cf to your computer and use it in GitHub Desktop.
Plantuml Domain Story Test
' based on https://github.com/johthor/DomainStory-PlantUML
' Styling
' ##################################
!global $iconColor = "#333333"
!global $iconScale = "0.8"
!global $iconScaleActor = "1"
!global $stepColor = "#cccccc"
!global $stepFontSize = 13
!global $stepFontColor = "#000000"
skinparam DefaultTextAlignment center
skinparam ArrowColor #333333
skinparam ArrowFontColor #333333
skinparam Padding 5
hide stereotypes
skinparam rectangle {
BackgroundColor none
BorderColor none
Shadowing false
}
skinparam rectangle<<boundary>> {
Shadowing false
StereotypeFontSize 0
FontColor #999999
BorderColor #999999
BorderStyle dashed
RoundCorner 15
}
skinparam note {
BackgroundColor #ffff99
BorderColor #808044
Shadowing false
}
' Icons
' ##################################
' Include common to use material icon macros.
!include <material/common>
' Actors: include filled and outlined icons
!include <material/crown>
!include <material/account_outline>
!include <material/account_multiple>
!include <material/account_multiple_outline>
!include <material/laptop>
!include <material/laptop_windows>
' Work objects: include filled and outlined icons
!include <material/file_outline>
!include <material/file>
!include <material/file_document>
!include <material/folder>
!include <material/folder_outline>
!include <material/phone>
'!include <material/phone_outline>
!include <material/at>
!include <material/email>
!include <material/message>
!include <material/message_outline>
!include <material/information>
!include <material/information_outline>
!include <material/settings_box>
!include <material/store>
' Elements
' ##################################
' Actors
!unquoted procedure Person($label, $alias = "", $color = "", $scale = "")
!if $alias == ""
!$alias = $label
!endif
!if $color == ""
!$color = $iconColor
!endif
!if $scale == ""
!$scale = $iconScaleActor
!endif
MA_ACCOUNT_OUTLINE($color, $scale, $alias, rectangle, $label)
!endprocedure
!unquoted procedure Group($label, $alias = "", $color = "", $scale = "")
!if $alias == ""
!$alias = $label
!endif
!if $color == ""
!$color = $iconColor
!endif
!if $scale == ""
!$scale = $iconScaleActor
!endif
MA_ACCOUNT_MULTIPLE($color, $scale, $alias, rectangle, $label)
!endprocedure
!unquoted procedure System($label, $alias = "", $color = "", $scale = "")
!if $alias == ""
!$alias = $label
!endif
!if $color == ""
!$color = $iconColor
!endif
!if $scale == ""
!$scale = $iconScaleActor
!endif
MA_LAPTOP($color, $scale, $alias, rectangle, $label)
!endprocedure
!unquoted procedure Merchant($label, $alias = "", $color = "", $scale = "")
!if $alias == ""
!$alias = $label
!endif
!if $color == ""
!$color = $iconColor
!endif
!if $scale == ""
!$scale = $iconScaleActor
!endif
MA_STORE($color, $scale, $alias, rectangle, $label)
!endprocedure
!unquoted procedure Customer($label, $alias = "", $color = "", $scale = "")
!if $alias == ""
!$alias = $label
!endif
!if $color == ""
!$color = $iconColor
!endif
!if $scale == ""
!$scale = $iconScaleActor
!endif
MA_CROWN($color, $scale, $alias, rectangle, $label)
!endprocedure
!unquoted procedure Process($label, $alias = "", $color = "", $scale = "")
!if $alias == ""
!$alias = $label
!endif
!if $color == ""
!$color = $iconColor
!endif
!if $scale == ""
!$scale = $iconScaleActor
!endif
MA_SETTINGS_BOX($color, $scale, $alias, rectangle, $label)
!endprocedure
' Work objects
!unquoted procedure Document($label, $alias = "", $color = "", $scale = "")
!if $alias == ""
!$alias = $label
!endif
!if $color == ""
!$color = $iconColor
!endif
!if $scale == ""
!$scale = $iconScale
!endif
MA_FILE_OUTLINE($color, $scale, $alias, rectangle, $label)
!endprocedure
!unquoted procedure Folder($label, $alias = "", $color = "", $scale = "")
!if $alias == ""
!$alias = $label
!endif
!if $color == ""
!$color = $iconColor
!endif
!if $scale == ""
!$scale = $iconScale
!endif
MA_FOLDER($color, $scale, $alias, rectangle, $label)
!endprocedure
!unquoted procedure Call($label, $alias = "", $color = "", $scale = "")
!if $alias == ""
!$alias = $label
!endif
!if $color == ""
!$color = $iconColor
!endif
!if $scale == ""
!$scale = $iconScale
!endif
MA_PHONE($color, $scale, $alias, rectangle, $label)
!endprocedure
!unquoted procedure Email($label, $alias = "", $color = "", $scale = "")
!if $alias == ""
!$alias = $label
!endif
!if $color == ""
!$color = $iconColor
!endif
!if $scale == ""
!$scale = $iconScale
!endif
MA_AT($color, $scale, $alias, rectangle, $label)
!endprocedure
!unquoted procedure Conversation($label, $alias = "", $color = "", $scale = "")
!if $alias == ""
!$alias = $label
!endif
!if $color == ""
!$color = $iconColor
!endif
!if $scale == ""
!$scale = $iconScale
!endif
MA_MESSAGE_OUTLINE($color, $scale, $alias, rectangle, $label)
!endprocedure
!unquoted procedure Info($label, $alias = "", $color = "", $scale = "")
!if $alias == ""
!$alias = $label
!endif
!if $color == ""
!$color = $iconColor
!endif
!if $scale == ""
!$scale = $iconScale
!endif
MA_INFORMATION_OUTLINE($color, $scale, $alias, rectangle, $label)
!endprocedure
' Activities
' ##################################
!global $objectCounter = 0
!unquoted procedure activity($step, $actor, $action, $object, $post, $target = "", $note = "")
' ensure object / create dynamic one
!$objectSeparator = %strpos($object, ":")
!if $objectSeparator > 0
!$objectCounter = %intval($objectCounter) + 1
!$objectType = %substr($object, 0, $objectSeparator)
!$objectLabel = %substr($object, $objectSeparator + 1)
!$object = $objectCounter + $objectType
%invoke_procedure($objectType, $objectLabel, $object)
!endif
' handle optional $post text
!if $target == ""
!$target = $post
!$post = ""
!else
!$post = ": " + $post
!endif
' handle forward or backward activity
!$direction = %strpos($step, "<")
!if $direction > 0
!$label = stepLabel(%substr($step, 0, $direction))
$object <-[$stepColor]- $actor : $label $action
$target <-[$stepColor]- $object $post
!else
!$label = stepLabel($step)
$actor -[$stepColor]-> $object : $label $action
$object -[$stepColor]-> $target $post
!endif
!if $note != ""
note right of $object: $note
!endif
!endprocedure
' Boundaries
' ##################################
!unquoted procedure Boundary($label)
rectangle "==$label" <<boundary>>
!endprocedure
!unquoted procedure Boundary($label, $alias)
rectangle "==$label" <<boundary>> as $alias
!endprocedure
' Helper
' ##################################
!unquoted function stepLabel($step)
!$result = " "+$step+" "
!if ($stepColor != "")
!$result = "<back:"+$stepColor+">"+$result+"</back>"
!endif
!if ($stepFontColor != "")
!$result = "<color:"+$stepFontColor+">"+$result+"</color>"
!endif
!if ($stepFontSize != "")
!$result = "<size:"+$stepFontSize+">"+$result+"</size>"
!endif
!return $result
!endfunction
@johthor
Copy link

johthor commented Apr 5, 2021

Hello @dirx,
I'm pleased that my simple macro collection was useful for somebody. I would like to reintegrate your code into DomainStory-Plantuml, as it seems more refined. Would you be willing to open a PR? Or would it be okay for me to integrate it myself.
Greetings Johannes

@dirx
Copy link
Author

dirx commented Apr 6, 2021

hi @Jothor,

yes - your collection was super useful and it helped to speed up documenting / visualizing domain stories after sessions a lot.

Main focus on my approach & experience with it - as far as i remember:

  • simplify the handling of work objects - no separate declaration required
  • use direction as parameter to have unique activity procedure - not sure if it was this helpful - direction seems to be more like a layout helper in many cases
  • be able to include single domain story files into one overview document and share their actors - this helped to bundle typical happy path use cases

Downside/challenge/quirks:

  • boundaries must be around activities & optionally actors
  • boundaries and layouts are still tricky and mostly unsatisfying - especially in overviews
  • nice label of actors should be optional second param

The cinema example looks like:

@startuml
!includeurl https://gist.githubusercontent.com/dirx/426e3099f07658965ee762cc70eba3cf/raw/9926b99465791c3825a7ea1fca2141ef874e6f6e/domain-story.puml

' top to down is default and usually gives better results in journeys with multiple stories
left to right direction

skinparam defaultFontSize 12
skinparam defaultFontName "Open Sans"

!global $stepColor = "#cccccc"
!global $stepFontSize = 13
!global $stepFontColor = "#000000"

Person(customer)

Boundary(cash counter) {
    Person(cashier)
    System(ticket system, ticketSystem)

    !global $stepFontSize = 20
    activity(1, customer, asks for, Conversation: reservation, -, cashier)
    !global $stepFontSize = 13
    activity(2, cashier, finds available seats in, Document: screen plan, with, ticketSystem)
    activity(3<, cashier, recommends, Conversation: available seats, to, customer)
    activity(4, customer, confirms, Conversation: offered seats, -, cashier)
    activity(5, cashier, marks seats as reserved in, Document: screen plan, with, ticketSystem)
    activity(6<, ticketSystem, generates, Info: reservation number, for, cashier)
    activity(7<, cashier, tells, Conversation: reservation number, to, customer)
}
@enduml

Please feel free to integrate what you like about that and improve it - and drop the stuff you do not need - actors like Customer / Merchant might be too specific.

Best
Dirk

@johthor
Copy link

johthor commented Apr 7, 2021

So I am finished with integration.
I may have over complicated a lot of things. 😁

If I'm not mistaken, most of it should still be compatible with your work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment