pull/2/head
Ricardo Niepel 8 years ago
parent c12f24f09f
commit a234d78b5c

@ -0,0 +1,86 @@
{
"C4_Person": {
"prefix": "Person",
"body": [
"Person(${1:alias}, \"${2:label}\")",
"$0"
],
"description": "Add Person to C4 diagram"
},
"C4_Person_Descr": {
"prefix": "Person with Description",
"body": [
"Person(${1:alias}, \"${2:label}\", \"${3:description}\")",
"$0"
],
"description": "Add Person with Description to C4 diagram"
},
"C4_Container": {
"prefix": "Container",
"body": [
"Container(${1:alias}, \"${2:label}\", \"${3:technology}\")",
"$0"
],
"description": "Add Container to C4 diagram"
},
"C4_Container_Descr": {
"prefix": "Container with Description",
"body": [
"Container(${1:alias}, \"${2:label}\", \"${3:technology}\", \"${4:description}\")",
"$0"
],
"description": "Add Container with Description to C4 diagram"
},
"C4_System": {
"prefix": "System",
"body": [
"System(${1:alias}, \"${2:label}\")",
"$0"
],
"description": "Add System to C4 diagram"
},
"C4_System_Descr": {
"prefix": "System with Description",
"body": [
"System(${1:alias}, \"${2:label}\", \"${3:description}\")",
"$0"
],
"description": "Add System with Description to C4 diagram"
},
"C4_Relationship": {
"prefix": "Relationship",
"body": [
"Rel(${1:from_alias}, ${2:to_alias}, \"${3:label}\")",
"$0"
],
"description": "Add unidirectional Relationship to C4 diagram"
},
"C4_Relationship_Techn": {
"prefix": "Relationship with Technology",
"body": [
"Rel(${1:from_alias}, ${2:to_alias}, \"${3:label}\", \"${4:technology}\")",
"$0"
],
"description": "Add unidirectional Relationship with Technology to C4 diagram"
},
"C4_Layout_Right": {
"prefix": "Layout to Right side",
"body": [
"Lay_R(${1:from_alias}, ${2:to_alias})",
"$0"
],
"description": "Add hidden layout line to put {to} to the right of {from}"
},
"C4_Layout_Left": {
"prefix": "Layout to Left side",
"body": [
"Lay_L(${1:from_alias}, ${2:to_alias})",
"$0"
],
"description": "Add hidden layout line to put {to} to the left of {from}"
}
}

@ -0,0 +1,109 @@
' Colors
' ##################################
!define PERSON_BG_COLOR #08427B
!define CONTAINER_BG_COLOR #438DD5
!define SYSTEM_BG_COLOR #999999
!define ELEMENT_FONT_COLOR #FFFFFF
!define TECHN_FONT_SIZE 12
' Styling
' ##################################
skinparam defaultTextAlignment center
skinparam wrapWidth 200
skinparam maxMessageSize 200
skinparam rectangle {
StereotypeFontSize 12
}
skinparam Arrow {
Color #666666
FontColor #666666
}
skinparam rectangle<<person>> {
StereotypeFontColor ELEMENT_FONT_COLOR
FontColor ELEMENT_FONT_COLOR
BackgroundColor PERSON_BG_COLOR
BorderColor #073B6F
}
skinparam rectangle<<container>> {
StereotypeFontColor ELEMENT_FONT_COLOR
FontColor ELEMENT_FONT_COLOR
BackgroundColor CONTAINER_BG_COLOR
BorderColor #3C7FC0
}
skinparam rectangle<<system>> {
StereotypeFontColor ELEMENT_FONT_COLOR
FontColor ELEMENT_FONT_COLOR
BackgroundColor SYSTEM_BG_COLOR
BorderColor #8A8A8A
}
skinparam package<<boundary>> {
StereotypeFontSize 0
FontColor #999999
BorderColor #cccccc
}
' Layout
' ##################################
!definelong LAYOUT_AS_SKETCH
skinparam backgroundColor #EEEBDC
skinparam handwritten true
skinparam defaultFontName "Comic Sans MS"
center footer <font color=red>Warning:</font> Created for discussion, needs to be validated
!enddefinelong
!definelong LAYOUT_WITH_LEGEND
hide stereotype
legend right
|= |= Type |
|<PERSON_BG_COLOR> | person |
|<CONTAINER_BG_COLOR> | container |
|<SYSTEM_BG_COLOR> | external system |
endlegend
!enddefinelong
!define LAYOUT_TOP_DOWN top to bottom direction
!define LAYOUT_LEFT_RIGHT left to right direction
' Elements
' ##################################
!define Person(e_alias, e_label) rectangle "==e_label" <<person>> as e_alias
!define Person(e_alias, e_label, e_descr) rectangle "==e_label\n\n e_descr" <<person>> as e_alias
!define Container(e_alias, e_label, e_techn) rectangle "==e_label\n//<size:TECHN_FONT_SIZE>[e_techn]</size>//" <<container>> as e_alias
!define Container(e_alias, e_label, e_techn, e_descr) rectangle "==e_label\n//<size:TECHN_FONT_SIZE>[e_techn]</size>//\n\n e_descr" <<container>> as e_alias
!define System(e_alias, e_label) rectangle "==e_label" <<system>> as e_alias
!define System(e_alias, e_label, e_descr) rectangle "==e_label\n\n e_descr" <<system>> as e_alias
!define Rel_(e_from,e_to, e_label, e_direction="") e_from -e_direction-> e_to : "===e_label"
!define Rel_(e_from,e_to, e_label, e_techn, e_direction="") e_from -e_direction-> e_to : "===e_label\n//<size:TECHN_FONT_SIZE>[e_techn]</size>//"
!define Rel(e_from,e_to, e_label) Rel_(e_from,e_to, e_label, "")
!define Rel(e_from,e_to, e_label, e_techn) Rel_(e_from,e_to, e_label, e_techn, "")
!define Rel_D(e_from,e_to, e_label) Rel_(e_from,e_to, e_label, "DOWN")
!define Rel_D(e_from,e_to, e_label, e_techn) Rel_(e_from,e_to, e_label, e_techn, "DOWN")
!define Rel_U(e_from,e_to, e_label) Rel_(e_from,e_to, e_label, "UP")
!define Rel_U(e_from,e_to, e_label, e_techn) Rel_(e_from,e_to, e_label, e_techn, "UP")
!define Rel_L(e_from,e_to, e_label) Rel_(e_from,e_to, e_label, "LEFT")
!define Rel_L(e_from,e_to, e_label, e_techn) Rel_(e_from,e_to, e_label, e_techn, "LEFT")
!define Rel_R(e_from,e_to, e_label) Rel_(e_from,e_to, e_label, "RIGHT")
!define Rel_R(e_from,e_to, e_label, e_techn) Rel_(e_from,e_to, e_label, e_techn, "RIGHT")
!define Lay_R(e_from, e_to) e_from -[hidden]R- e_to
!define Lay_L(e_from, e_to) e_from -[hidden]L- e_to

@ -1,2 +1,140 @@
# C4-PlantUML
C4-PlantUML combines the benefits of PlantUML and the C4 model for providing a simple way of describing and communicate software architectures
C4-PlantUML combines the benefits of [PlantUML](http://en.plantuml.com/) and the [C4 model](https://c4model.com/) for providing a simple way of describing and communicate software architectures - especially during up-front design sessions - with an intuitive language using open source and platform independent tools.
C4-PlantUML includes macros, stereotypes, and other goodies (like VSCode Snippets) for creating C4 diagrams with PlantUML.
## Background
[PlantUML](http://en.plantuml.com/) is an open source project that allows you to create UML diagrams.
Diagrams are defined using a simple and intuitive language.
Images can be generated in PNG, in SVG or in LaTeX format.
PlantUML was created to allow the drawing of UML diagrams, using a simple and human readable text description.
Because it does not prevent you from drawing inconsistent diagrams, it is a drawing tool and not a modeling tool.
It is the most used text-based diagram drawing tool with [extensive support into wikis and forums, text editors and IDEs, use by different programming languages and documentation generators](http://en.plantuml.com/running).
The [C4 model](https://c4model.com/) for software architecture is an "abstraction-first" approach to diagramming, based upon abstractions that reflect how software architects and developers think about and build software.
The small set of abstractions and diagram types makes the C4 model easy to learn and use.
C4 stands for context, containers, components, and code — a set of hierarchical diagrams that you can use to describe your software architecture at different zoom levels, each useful for different audiences.
The C4 model was created as a way to help software development teams describe and communicate software architecture, both during up-front design sessions and when retrospectively documenting an existing codebase.
More information can be found here:
* [The C4 model for software architecture](https://c4model.com/)
* [REAL WORLD PlantUML - Sample Gallery](https://real-world-plantuml.com/)
* [Visualising and documenting software architecture cheat sheets](http://www.codingthearchitecture.com/2017/04/27/visualising_and_documenting_software_architecture_cheat_sheets.html)
* [PlantUML and Structurizr - Create models not diagrams](http://www.codingthearchitecture.com/2016/12/08/plantuml_and_structurizr.html)
## Getting Started
At the top of your C4 PlantUML `.puml` file, you need to include the `C4_Container.puml` file found in the `root` of this repo.
To be independent of any internet connectifity, you can also download `C4_Container.puml` and reference it locally with
```plantuml
!include path/to/C4_Container.puml
```
If you want to use the always up-to-date version in this repo, use the following:
```plantuml
!includeurl https://raw.githubusercontent.com/RicardoNiepel/C4-PlantUML/master/C4_Container.puml
```
After you have inlcluded `C4_Container.puml` you can use the defined macro definitions for the C4 elements: `Person`, `System`, `Container`, `Relationship`.
```plantuml
@startuml Basic Sample
!include C4_Container.puml
Person(personAlias, "Label", "Optional Description")
Container(containerAlias, "Label", "Technology", "Optional Description")
System(systemAlias, "Label", "Optional Description")
Rel(personAlias, containerAlias, "Label", "Optional Technology")
@enduml
```
In addition to this, it is also possible to define a system boundary.
Take a look a look at the following sample of a C4 Container Diagram:
```plantuml
@startuml Basic Sample
!include C4_Container.puml
Person(admin, "Administrator")
package "Sample System" <<boundary>> as c1 {
Container(web_app, "Web Application", "C#, ASP.NET Core 2.1 MVC", "Allows users to compare multiple Twitter timelines")
}
System(twitter, "Twitter")
Rel(admin, web_app, "Uses", "HTTPS")
Rel(web_app, twitter, "Gets tweets from", "HTTPS")
@enduml
```
## Snipptes for Visual Studio Code
Lorem
https://medium.com/hack-visual-studio-code/share-snippets-with-your-team-in-vs-code-817801e853fb
## Layout Options
PlantUML uses [Graphviz](https://www.graphviz.org/) for his graph visualization. Thus the rendering itself is done automatically for you - that it one of the biggest advantages of using PlantUML.
...and also sometimes one of the biggest disadvantages, if the rendering is not what the user intended.
For this reason, C4-PlantUML also comes with some layout options.
### LAYOUT_TOP_DOWN or LAYOUT_LEFT_RIGHT
With the two macros `LAYOUT_TOP_DOWN` and `LAYOUT_LEFT_RIGHT` it is possible to easily change the flow visualization of the diagram. `LAYOUT_TOP_DOWN` is the default.
```plantuml
@startuml Basic Sample
!include C4_Container.puml
' Not needed because this is the default
LAYOUT_TOP_DOWN
Person(admin, "Administrator")
package "Sample System" <<boundary>> as c1 {
Container(web_app, "Web Application", "C#, ASP.NET Core 2.1 MVC", "Allows users to compare multiple Twitter timelines")
}
System(twitter, "Twitter")
Rel(admin, web_app, "Uses", "HTTPS")
Rel(web_app, twitter, "Gets tweets from", "HTTPS")
@enduml
```
Using `LAYOUT_LEFT_RIGHT`
```plantuml
@startuml Basic Sample
!include C4_Container.puml
LAYOUT_LEFT_RIGHT
Person(admin, "Administrator")
package "Sample System" <<boundary>> as c1 {
Container(web_app, "Web Application", "C#, ASP.NET Core 2.1 MVC", "Allows users to compare multiple Twitter timelines")
}
System(twitter, "Twitter")
Rel(admin, web_app, "Uses", "HTTPS")
Rel(web_app, twitter, "Gets tweets from", "HTTPS")
@enduml
```
### LAYOUT_WITH_LEGEND
Colors can help to add additional information or simply to make the diagram more aesthetically pleasing.
## Advanced Samples

@ -0,0 +1,48 @@
@startuml "bigbankplc"
!include ..\C4_Container.puml
LAYOUT_TOP_DOWN
'LAYOUT_AS_SKETCH
LAYOUT_WITH_LEGEND
Person(customer, Customer, "A customer of the bank, with personal bank accounts")
package "Internet Banking System" <<boundary>> as c1 {
Container(web_app, "Web Application", "Java, Spring MVC", "Delivers the static content and the Internet banking SPA")
Container(spa, "Single-Page App", "JavaScript, Angular", "Provides all the Internet banking functionality to cutomers via their web browser")
Container(mobile_app, "Mobile App", "C#, Xamarin", "Provides a limited subset of the Internet banking functionality to customers via their mobile device")
Container(backend_api, "API Application", "Java, Docker Container", "Provides Internet banking functionality via API")
Container(database, "Database", "SQL Database", "Stores user registraion information, hased auth credentials, access logs, etc.")
}
System(email_system, "E-Mail System", "The internal Microsoft Exchange system")
System(banking_system, "Mainframe Banking System", "Stores all of the core banking information about customers, accounts, transactions, etc.")
Rel(customer, web_app, "Uses", "HTTPS")
Rel(customer, spa, "Uses", "HTTPS")
Rel(customer, mobile_app, "Uses")
Rel_R(web_app, spa, "Delivers")
Rel(spa, backend_api, "Uses", "async, JSON/HTTPS")
Rel(mobile_app, backend_api, "Uses", "async, JSON/HTTPS")
Rel_L(backend_api, database, "Reads from and writes to", "sync, JDBC")
Rel_R(backend_api, banking_system, "Uses", "sync/async, XML/HTTPS")
Rel_U(backend_api, email_system, "Sends e-mails using", "sync, SMTP")
Rel(email_system, customer, "Sends e-mails to")
rectangle test
email_system -UP-> test
test -LEFT-> customer
hide test
@enduml

@ -0,0 +1,49 @@
@startuml "bigbankplc"
!include ..\C4_Container.puml
skinparam wrapWidth 200
skinparam maxMessageSize 200
LAYOUT_TOP_DOWN
'LAYOUT_AS_SKETCH
LAYOUT_WITH_LEGEND
Person(customer, Customer, "A customer")
package "Customer Information System" <<boundary>> as c1 {
Container(app, "Customer Application", "Javascript, Angular", "Allows customers to manage their profile")
Container(customer_service, "Customer Service", "Java, Spring Boot", "The point of access for customer information")
Container(message_bus, "Message Bus", "RabbitMQ", "Transport for business events")
Container(reporting_service, "Reporting Service", "Ruby", "Creates normalised data for reporting purposes")
Container(audit_service, "Audit Service", "C#/.NET", "Provides organisation-wide auditing facilities")
Container(customer_db, "Customer Database", "Oracle 12c", "Stores customer information")
Container(reporting_db, "Reporting Database", "MySQL", "Stores a normalized version of all business data for ad hoc reporting purposes")
Container(audit_store, "Audit Store", "Event Store", "Stores information about events that have happened")
}
Rel(customer, app, "Uses", "HTTPS")
Rel_R(app, customer_service, "Updates customer information using", "async, JSON/HTTPS")
Rel_L(customer_service, app, "Sends events to", "WebSocket")
Rel_R(customer_service, message_bus, "Sends customer update events to")
Rel(customer_service, customer_db, "Stores data in", "JDBC")
Rel(message_bus, reporting_service, "Sends customer update events to")
Rel(message_bus, audit_service, "Sends customer update events to")
Rel(reporting_service, reporting_db, "Stores data in")
Rel(audit_service, audit_store, "Stores events in")
Lay_R(reporting_service, audit_service)
@enduml

@ -0,0 +1,49 @@
@startuml "bigbankplc"
!include ..\C4_Container.puml
LAYOUT_TOP_DOWN
'LAYOUT_AS_SKETCH
LAYOUT_WITH_LEGEND
Person(anonymous_user, "Anonymous User")
Person(aggregated_user, "Aggregated User")
Person(administration_user, "Administration User")
package "techtribes.js" <<boundary>> as c1 {
Container(web_app, "Web Application", "Java, Spring MVC, Tomcat 7.x", "Allows users to view people, tribes, content, events, jobs, etc. from the local tech, digital and IT sector")
Container(rel_db, "Relational Database", "MySQL 5.5.x", "Stores people, tribes, tribe membership, talks, events, jobs, badges, GitHub repos, etc.")
Container(filesystem, "File System", "FAT32", "Stores search indexes")
Container(nosql, "NoSQL Data Store", "MongoDB 2.2.x", "Stores from RSS/Atom feeds (blog posts) and tweets")
Container(updater, "Updater", "Java 7 Console App", "Updates profiles, tweets, GitHub repos and content on a scheduled basis")
}
System(twitter, "Twitter")
System(github, "GitHub")
System(blogs, "Blogs")
Rel(anonymous_user, web_app, "Uses", "HTTPS")
Rel(aggregated_user, web_app, "Uses", "HTTPS")
Rel(administration_user, web_app, "Uses", "HTTPS")
Rel(web_app, rel_db, "Reads from and writes to", "SQL/JDBC, post 3306")
Rel(web_app, filesystem, "Reads from")
Rel(web_app, nosql, "Reads from", "MongoDB wire protocol, port 27017")
Rel_U(updater, rel_db, "Reads from and writes data to", "SQL/JDBC, post 3306")
Rel_U(updater, filesystem, "Writes to")
Rel_U(updater, nosql, "Reads from and writes to", "MongoDB wire protocol, port 27017")
Rel(updater, twitter, "Gets profile information and tweets from", "HTTPS")
Rel(updater, github, "Gets information about public code repositories from", "HTTPS")
Rel(updater, blogs, "Gets content using RSS and Atom feeds from", "HTTP")
Lay_R(rel_db, filesystem)
@enduml
Loading…
Cancel
Save