Tuc Parts
There must be at lease one part of the use-case in the Tuc definition.
Use-Case Parts
- Lifeline
- Section
- Service Method Call
- Post Data
- Read Data
- Post Event
- Read Event
- Handle Event In Stream
- Group
- If
- Loop
- Do
- Left Note
- Note
- Right Note
Lifeline
Life line is the execution of the Initiator.
- It may contain other use-case parts, indented by one level.
- It activates an Initiator and deactivates it, in the end of a lifeline.
Syntax
{InitiatorService}
// indented execution of the lifeline
Example
// myDomain.fsx
type MainService = Initiator
tuc Lifeline
participants
MainService My as "Main Service"
MainService
"this is a lifeline"
Results:
@startuml lifeline
== Lifeline ==
actor "Main Service" as MainService <<My>>
activate MainService
note over MainService: this is a lifeline
deactivate MainService
@enduml
Section
It is a simple divider in the puml.
- It must not be indented (so it can not be in any execution, body, etc.)
- It must have a name
Syntax
section {Section name}
Example
tuc Section
participants
MainService My as "Main Service"
section There is just a section
Results:
@startuml section
== Section ==
actor "Main Service" as MainService <<My>>
activate MainService
== There is just a section ==
deactivate MainService
@enduml
Service Method Call
It is the execution of the Service Method by a caller.
- It must be in the execution of another caller (lifeline, other method call, etc.)
- It may contain other use-case parts, indented by one level.
- It activates a Service and deactivates it, in the end of an execution, returning a Method’s return value to the caller.
Syntax
{ServiceName}.{MethodName}
// indented execution of the method
Service Type is found in the Domain Types, it must contain a MethodName as a field with a function (method). The type of the Method is used in the puml.
NOTE: Service will became a caller in its execution body.
Example
// myDomain.fsx
type MainService = Initiator
type Service = {
Method: Input -> Output
}
and Input = Input
and Output = Output
tuc Service Method Call
participants
MainService My as "Main Service"
Service My
MainService // MainService is the caller
Service.Method // Method `Method` is called on the `Service`
"this is part of execution" // This is part of the Method execution
Service.MethodWithMoreArgs // Method `MethodWithMoreArgs` is called on the `Service`
"this is part of execution" // This is part of the Method execution
Results:
@startuml service-method-call
== Service Method Call ==
actor "Main Service" as MainService <<My>>
participant "Service" as Service <<My>>
activate MainService
MainService -> Service ++: Method(Input)
note over Service: this is part of execution
Service --> MainService --: Output
MainService -> Service ++: MethodWithMoreArgs(\n Id, \n int * string, \n Input\n)
note over Service: this is part of execution
Service --> MainService --: Output
deactivate MainService
@enduml
Post Data
Data can be posted to the Data Object of its type.
- It must be in the execution of another caller (lifeline, other method call, etc.)
- It can not contain other use-case parts.
- It validates you are sending a correct data type to the correct Data Object.
Syntax
{DataType} -> [{DataObjectName}]
Example
// myDomain.fsx
// common types
type Id = Id
type Database<'Entity> = Database of 'Entity list
// domain types
type MainService = Initiator
type InteractionDatabase = InteractionDatabase of Database<InteractionEntity>
and InteractionEntity = {
Id: Id
InteractionData: string
}
tuc Post Data
participants
MainService My as "Main Service"
[InteractionDatabase] My
[InteractionCache] My
MainService // MainService is the caller
InteractionEntity -> [InteractionDatabase] // InteractionEntity is posted to the Database
// Even concrete data can be posted to the Data object
InteractionEvent.Confirmed -> [InteractionCache]
InteractionEvent.Rejected -> [InteractionCache]
InteractionEvent.Rejected.Expired -> [InteractionCache]
InteractionEvent.Rejected.Rejected -> [InteractionCache]
Results:
@startuml post-data
== Post Data ==
actor "Main Service" as MainService <<My>>
database "InteractionDatabase" as InteractionDatabase <<My>>
database "InteractionCache" as InteractionCache <<My>>
activate MainService
MainService ->> InteractionDatabase: InteractionEntity
MainService ->> InteractionCache: [[{InteractionEvent.Confirmed}Confirmed]]
MainService ->> InteractionCache: [[{InteractionEvent.Rejected}Rejected]]
MainService ->> InteractionCache: [[{InteractionEvent.Rejected.Expired}Expired]]
MainService ->> InteractionCache: [[{InteractionEvent.Rejected.Rejected}Rejected]]
deactivate MainService
@enduml
Read Data
Data can be read from the Data object of its type.
- It must be in the execution of another caller (lifeline, other method call, etc.)
- It can not contain other use-case parts.
- It validates you are reading a correct event type from the correct Stream.
Syntax
[{DataObjectName}] -> {DataType}
Example
// myDomain.fsx
// common types
type Id = Id
type Database<'Entity> = Database of 'Entity list
// domain types
type MainService = Initiator
type InteractionDatabase = InteractionDatabase of Database<InteractionEntity>
and InteractionEntity = {
Id: Id
InteractionData: string
}
tuc Read Data
participants
MainService My as "Main Service"
[InteractionDatabase] My
[InteractionCache] My
MainService // MainService is the caller
[InteractionDatabase] -> InteractionEntity // InteractionEntity is read from the Database
// Even concrete data can be read from the Data object
[InteractionCache] -> InteractionEvent.Confirmed
[InteractionCache] -> InteractionEvent.Rejected
[InteractionCache] -> InteractionEvent.Rejected.Expired
[InteractionCache] -> InteractionEvent.Rejected.Rejected
Results:
@startuml read-data
== Read Data ==
actor "Main Service" as MainService <<My>>
database "InteractionDatabase" as InteractionDatabase <<My>>
database "InteractionCache" as InteractionCache <<My>>
activate MainService
InteractionDatabase ->> MainService: InteractionEntity
InteractionCache ->> MainService: [[{InteractionEvent.Confirmed}Confirmed]]
InteractionCache ->> MainService: [[{InteractionEvent.Rejected}Rejected]]
InteractionCache ->> MainService: [[{InteractionEvent.Rejected.Expired}Expired]]
InteractionCache ->> MainService: [[{InteractionEvent.Rejected.Rejected}Rejected]]
deactivate MainService
@enduml
Post Event
Event can be posted to the Stream of its type.
- It must be in the execution of another caller (lifeline, other method call, etc.)
- It can not contain other use-case parts.
- It validates you are sending a correct event type to the correct Stream.
Syntax
{EventType} -> [{TypeName}Stream]
NOTE: It is the special post to the Data object, which allows you to go deeper to the Type definition.
Example
// myDomain.fsx
// common types
type Stream<'Event> = Stream of 'Event list
// domain types
type MainService = Initiator
type InteractionStream = InteractionStream of Stream<InteractionEvent>
and InteractionEvent =
| Confirmed of ConfirmedEvent
| Rejected of RejectedEvent
and ConfirmedEvent = ConfirmedEvent
and RejectedEvent =
| Expired
| Rejected
tuc Post Event
participants
MainService My as "Main Service"
[InteractionStream] My
MainService // MainService is the caller
InteractionEvent -> [InteractionStream] // InteractionEvent is posted to the stream
// Even concrete events can be posted to the stream
InteractionEvent.Confirmed -> [InteractionStream]
InteractionEvent.Rejected -> [InteractionStream]
InteractionEvent.Rejected.Expired -> [InteractionStream]
InteractionEvent.Rejected.Rejected -> [InteractionStream]
Results:
@startuml post-event
== Post Event ==
actor "Main Service" as MainService <<My>>
collections "InteractionStream" as InteractionStream <<My>>
activate MainService
MainService ->> InteractionStream: InteractionEvent
MainService ->> InteractionStream: [[{InteractionEvent.Confirmed}Confirmed]]
MainService ->> InteractionStream: [[{InteractionEvent.Rejected}Rejected]]
MainService ->> InteractionStream: [[{InteractionEvent.Rejected.Expired}Expired]]
MainService ->> InteractionStream: [[{InteractionEvent.Rejected.Rejected}Rejected]]
deactivate MainService
@enduml
Read Event
Event can be read from the Stream of its type.
- It must be in the execution of another caller (lifeline, other method call, etc.)
- It can not contain other use-case parts.
- It validates you are reading a correct event type from the correct Stream.
Syntax
[{TypeName}Stream] -> {EventType}
NOTE: It is the special read from the Data object, which allows you to go deeper to the Type definition.
Example
// myDomain.fsx
// common types
type Stream<'Event> = Stream of 'Event list
// domain types
type MainService = Initiator
type InteractionStream = InteractionStream of Stream<InteractionEvent>
and InteractionEvent =
| Confirmed of ConfirmedEvent
| Rejected of RejectedEvent
and ConfirmedEvent = ConfirmedEvent
and RejectedEvent =
| Expired
| Rejected
tuc Read Event
participants
MainService My as "Main Service"
[InteractionStream] My
MainService // MainService is the caller
[InteractionStream] -> InteractionEvent // InteractionEvent is read from the stream
// Even concrete events can be read from the stream
[InteractionStream] -> InteractionEvent.Confirmed
[InteractionStream] -> InteractionEvent.Rejected
[InteractionStream] -> InteractionEvent.Rejected.Expired
[InteractionStream] -> InteractionEvent.Rejected.Rejected
Results:
@startuml read-event
== Read Event ==
actor "Main Service" as MainService <<My>>
collections "InteractionStream" as InteractionStream <<My>>
activate MainService
InteractionStream ->> MainService: InteractionEvent
InteractionStream ->> MainService: [[{InteractionEvent.Confirmed}Confirmed]]
InteractionStream ->> MainService: [[{InteractionEvent.Rejected}Rejected]]
InteractionStream ->> MainService: [[{InteractionEvent.Rejected.Expired}Expired]]
InteractionStream ->> MainService: [[{InteractionEvent.Rejected.Rejected}Rejected]]
deactivate MainService
@enduml
Handle Event In Stream
It is the execution of the Service Handler, invoked by an Stream Event..
- It must start after a Stream name, indented by one level.
- It may contain other use-case parts, indented by one level.
- It activates a Service and deactivates it, in the end of an execution, returning nothing to the caller.
Syntax
[{TypeName}Stream]
{ServiceName}.{HandlerName}
// indented execution of the method
Service Type is found in the Domain Types, it must contain a HandlerName as a field with a function (handler). The type of the Handler is used for checking a Stream Type.
NOTE: Service will became a caller in its execution body.
Example
// myDomain.fsx
// common types
type Stream<'Event> = Stream of 'Event list
type StreamHandler<'Event> = StreamHandler of ('Event -> unit)
// domain types
type InteractionStream = InteractionStream of Stream<InteractionEvent>
and InteractionEvent =
| Confirmed of ConfirmedEvent
| Rejected of RejectedEvent
and ConfirmedEvent = ConfirmedEvent
and RejectedEvent =
| Expired
| Rejected
type StreamListener = {
OnInteractionEvent: StreamHandler<InteractionEvent>
}
tuc Handle Event in Stream
participants
StreamListener My
[InteractionStream] My
[InteractionStream] // Stream of the Event type of the handler
StreamListener.OnInteractionEvent // Handler `OnInteractionEvent` is called on the `StreamListener`
"this is part of execution" // This is part of the Handler execution
Results:
@startuml handle-event-in-stream
== Handle Event in Stream ==
participant "StreamListener" as StreamListener <<My>>
collections "InteractionStream" as InteractionStream <<My>>
InteractionStream ->> StreamListener: OnInteractionEvent(InteractionEvent)
activate StreamListener
note over StreamListener: this is part of execution
deactivate StreamListener
@enduml
Group
Allows to group use-case parts together.
- It may be indented (so it can be in any execution, body, etc.)
- It must have a name
- It must contain at least one use-case part, indented by one level.
Syntax
group {Group name}
// indented body of the group
Example
tuc Group
participants
MainService My as "Main Service"
group Grouped together
MainService
do something
MainService
do something else
Results:
@startuml group
== Group ==
actor "Main Service" as MainService <<My>>
activate MainService
group Grouped together
hnote over MainService
do: something
end hnote
hnote over MainService
do: something else
end hnote
end
deactivate MainService
@enduml
If
Allows to group use-case parts together by a condition.
- It may be indented (so it can be in any execution, body, etc.)
- It must have a condition
- It must contain at least one use-case part, indented by one level.
- It may have an
else
branch, when it does, it must be on the same level as is theif
. Andelse
must contain at least one use-case part, indented by one level.
Syntax
if {Condition}
// indented body of the if
With else
if {Condition}
// indented body of the if
else
// indented body of the else
NOTE: There is no else if
syntax, if you need to use it, you need to have other if/if-else
in the else
branch.
With another if
in else
if {Condition}
// indented body of the if
else
if {Condition}
// indented body of the else-if
Example
tuc If-else
participants
MainService My as "Main Service"
if the weather is nice
MainService
if it is over a 30°C
do
nothing
because its to hot
else
do some work
else
if it is raining
MainService
do work
Results:
@startuml if-else
== If-else ==
actor "Main Service" as MainService <<My>>
activate MainService
alt the weather is nice
alt it is over a 30°C
hnote over MainService
do:
nothing
because its to hot
end hnote
else
hnote over MainService
do: some work
end hnote
end
else
alt it is raining
hnote over MainService
do: work
end hnote
end
end
deactivate MainService
@enduml
Loop
Allows to group use-case parts together in a loop with a condition.
- It may be indented (so it can be in any execution, body, etc.)
- It must have a condition
- It must contain at least one use-case part, indented by one level.
Syntax
loop {Condition}
// indented body of the loop
Example
tuc Loop
participants
MainService My as "Main Service"
loop until it's done
MainService
do something
Results:
@startuml loop
== Loop ==
actor "Main Service" as MainService <<My>>
activate MainService
loop until it's done
hnote over MainService
do: something
end hnote
end
deactivate MainService
@enduml
Note
A note above a caller
- It must be in the execution of another caller (lifeline, other method call, etc.)
- It may have one or more lines
- It may contain a formatting, supported by a PlantUML
Syntax
Single line note
"{this is a note}"
Multi line note
"""
{This
is
a multi line
note}
"""
Example
tuc Note
participants
MainService My as "Main Service"
MainService
"this is a note"
"""
This is **bold**
This is *italics*
This is ""monospaced""
This is --stroked--
This is __underlined__
This is ~~waved~~
This is <back:cadetblue><size:18>formatted</size></back>
<u:red>This</u> is <color #118888>displayed</color> **<color purple>on a </color> <s:red>Main</strike> Service**.
"""
Results:
@startuml note
== Note ==
actor "Main Service" as MainService <<My>>
activate MainService
note over MainService: this is a note
note over MainService
This is **bold**
This is //italics//
This is ""monospaced""
This is --stroked--
This is __underlined__
This is ~~waved~~
This is <back:cadetblue><size:18>formatted</size></back>
<u:red>This</u> is <color #118888>displayed</color> **<color purple>on a </color> <s:red>Main</strike> Service**.
end note
deactivate MainService
@enduml
Left Note
A note on the left side of the execution
- It should be in the execution of another caller (lifeline, other method call, etc.)
- It may have one or more lines
- It may contain a formatting, supported by a PlantUML
Syntax
Single line left note
"<{this is a note}"
Multi line left note
"<"
{This
is
a multi line
note}
"<"
Example
tuc Left Note
participants
MainService My as "Main Service"
Service My
MainService
Service.Method
"< this is a note"
"<"
This is **bold**
This is *italics*
This is ""monospaced""
This is --stroked--
This is __underlined__
This is ~~waved~~
This is <back:cadetblue><size:18>formatted</size></back>
<u:red>This</u> is <color #118888>displayed</color> **<color purple>on a </color> <s:red>Main</strike> Service**.
"<"
Results:
@startuml left-note
== Left Note ==
actor "Main Service" as MainService <<My>>
participant "Service" as Service <<My>>
activate MainService
MainService -> Service ++: Method(Input)
note left: this is a note
note left
This is **bold**
This is //italics//
This is ""monospaced""
This is --stroked--
This is __underlined__
This is ~~waved~~
This is <back:cadetblue><size:18>formatted</size></back>
<u:red>This</u> is <color #118888>displayed</color> **<color purple>on a </color> <s:red>Main</strike> Service**.
end note
Service --> MainService --: Output
deactivate MainService
@enduml
Right Note
A note on the right side of the execution
- It should be in the execution of another caller (lifeline, other method call, etc.)
- It may have one or more lines
- It may contain a formatting, supported by a PlantUML
Syntax
Single line right note
">{this is a note}"
Multi line right note
">"
{This
is
a multi line
note}
">"
Example
tuc Right Note
participants
MainService My as "Main Service"
Service My
MainService
Service.Method
"> this is a note"
">"
This is **bold**
This is *italics*
This is ""monospaced""
This is --stroked--
This is __underlined__
This is ~~waved~~
This is <back:cadetblue><size:18>formatted</size></back>
<u:red>This</u> is <color #118888>displayed</color> **<color purple>on a </color> <s:red>Main</strike> Service**.
">"
Results:
@startuml right-note
== Right Note ==
actor "Main Service" as MainService <<My>>
participant "Service" as Service <<My>>
activate MainService
MainService -> Service ++: Method(Input)
note right: this is a note
note right
This is **bold**
This is //italics//
This is ""monospaced""
This is --stroked--
This is __underlined__
This is ~~waved~~
This is <back:cadetblue><size:18>formatted</size></back>
<u:red>This</u> is <color #118888>displayed</color> **<color purple>on a </color> <s:red>Main</strike> Service**.
end note
Service --> MainService --: Output
deactivate MainService
@enduml
Do
A special note above a caller
- It must be in the execution of another caller (lifeline, other method call, etc.)
- It may have one or more lines
- It must contain at least one action, indented by one level, when it is multi-line
- It may contain a formatting, supported by a PlantUML
- It will start with a
do:
key word and will have another shape, then regular note - It may contain a formatting, supported by a PlantUML
Syntax
Single line do
do {Something}
Multi line note
do
{More
than
one
thing}
Example
tuc Do
participants
MainService My as "Main Service"
MainService
do Some work
do
one thing
other thing
and the last thing
Results:
@startuml do
== Do ==
actor "Main Service" as MainService <<My>>
activate MainService
hnote over MainService
do: Some work
end hnote
hnote over MainService
do:
one thing
other thing
and the last thing
end hnote
deactivate MainService
@enduml