A Superficial Deep Dive into Software Visualization

Whiteboard Sketch Whiteboard Sketch Whiteboard Sketch Whiteboard Sketch
Images from https://c4model.com

PlantUML

Textual descriptions for UML diagrams

Entity Relationships

Source


              @startuml

              package de.homelabs.webapps.workbench.menu {
                interface IMenuItem {
                  String getLink()
                  String getText()
                  String getTitle()
                }

                interface IMenu {
                  MenuItem getItems()
                  boolean addItem()
                  boolean addItems(List MenuItem)
                }

                interface IMenuManager {
                  IMenu getMenu(MenuType menuType)
                  boolean addMenu(MenuType menuType, IMenu menu)
                }

                enum MenuType {
                  MAINMENU
                  SUBMENU
                }

                Class MainMenu
                Class MainMenuItem
              }

              IMenu *-- IMenuItem

              MainMenu --|> IMenu
              MainMenuItem --|> IMenuItem

              IMenuManager -- MenuType
              IMenuManager --o IMenu

              @enduml
            

Program Flow

Source


              @startuml
              title Servlet Container

              (*) --> "ClickServlet.handleRequest()"
              --> "new Page"

              if "Page.onSecurityCheck" then
                ->[true] "Page.onInit()"

                if "isForward?" then
                 ->[no] "Process controls"

                 if "continue processing?" then
                   -->[yes] ===RENDERING===
                 else
                   -->[no] ===REDIRECT_CHECK===
                 endif

                else
                 -->[yes] ===RENDERING===
                endif

                if "is Post?" then
                  -->[yes] "Page.onPost()"
                  --> "Page.onRender()" as render
                  --> ===REDIRECT_CHECK===
                else
                  -->[no] "Page.onGet()"
                  --> render
                endif

              else
                -->[false] ===REDIRECT_CHECK===
              endif

              if "Do redirect?" then
               ->[yes] "redirect request"
               --> ==BEFORE_DESTROY===
              else
               if "Do Forward?" then
                -left->[yes] "Forward request"
                --> ==BEFORE_DESTROY===
               else
                -right->[no] "Render page template"
                --> ==BEFORE_DESTROY===
               endif
              endif

              --> "Page.onDestroy()"
              -->(*)

              @enduml
            

Event Sequences

Source


              @startuml

              actor browser
              participant nginx
              participant backend
              participant keycloak
              browser -> nginx: /library (558.0B)
              browser <-- nginx: 304  (266.0B)
              browser -> backend: /api/library (464.0B)
              browser <-- backend: 302   [OAuth_Token_Request_State] (547.0B)
              browser -> keycloak: /auth/realms/akvo/protocol/openid-connect/auth (0.7KB)
              browser <-- keycloak: 200 html  [KC_RESTART] (4.8KB)
              browser -> backend: /api/library (582.0B)
              browser <-- backend: 302   [OAuth_Token_Request_State] (547.0B)
              browser -> keycloak: /auth/realms/akvo/protocol/openid-connect/auth (0.7KB)
              browser <-- keycloak: 200 html  [KC_RESTART] (4.8KB)
              browser -> keycloak: /auth/realms/akvo/login-actions/authenticate [POST] (122.0B)
              browser <-- keycloak: 302   [KEYCLOAK_REMEMBER_ME] (1.4KB)
              browser -> backend: /api/library (1.0KB)
              backend -> keycloak: /auth/realms/akvo/protocol/openid-connect/token [POST] (646.0B)
              backend <-- keycloak: 200 json (4.2KB)
              backend -> keycloak: /auth/realms/akvo/protocol/openid-connect/certs (166.0B)
              backend <-- keycloak: 200 json (0.7KB)
              browser <-- backend: 302   [OAuth_Token_Request_State] (411.0B)
              browser -> backend: /api/library (0.8KB)
              backend -> keycloak: /auth/realms/akvo/authz/entitlement/akvo-lumen-confidential (1.7KB)
              backend <-- keycloak: 200 json (2.2KB)
              browser <-- backend: 200 json (1.0KB)
              browser -> nginx: /library (619.0B)
              browser <-- nginx: 304  (266.0B)
              browser -> backend: /api/library (525.0B)
              browser <-- backend: 200 json (1.0KB)
              browser -> backend: /api/datasets/ds-1 (536.0B)
              browser <-- backend: 200 json (0.7KB)
              browser -> backend: /api/library (525.0B)
              browser <-- backend: 200 json (1.0KB)
              note over browser, nginx: ->1.2KB/<-532.0B
              note over browser, backend: ->4.4KB/<-5.3KB
              note over browser, keycloak: ->1.6KB/<-11.0KB
              note over backend, keycloak: ->2.5KB/<-7.1KB

              @enduml
            

‘Personal Touch’


              @startuml "bigbankplc"
              !include <C4/C4_Container.puml>

              skinparam wrapWidth 200
              skinparam maxMessageSize 200

              LAYOUT_TOP_DOWN
              LAYOUT_WITH_LEGEND()

              Person(customer, Customer, "A customer")

              System_Boundary(c1, "Customer Information") {
                  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")

                  ContainerDb(customer_db, "Customer Database", "Oracle 12c", "Stores customer information")

                  ContainerDb(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
            

How do I use this?

Tons of Integrations

GitLab Visual Studio Code on-line ‘editors’: demo server, LiveUML, PlantUML Editor

Still… something was missing…


                
                  Joris -> "Eindhoven Front-End Meetup" : Thanks for Listening!
                  Joris -> "Eindhoven Front-End Meetup" : Get Visualizing!