Ask HN: Visualizing software designs, especially of large systems (if at all)?
I learned about UML in a course, but have never used it or seen it in practice as a junior developer. Sometimes I'll see a flowchart, but that's not too common. Is this the same in other companies?
With some of our code, the designers are either gone or sometimes unavailable, and it can be tricky to see how all the pieces fit together. A good IDE makes the job a little easier (finding references, ctrl+click to go to declarations, etc.), but it'd be nice to have a diagram or something for visualization.
So, is it a good idea to try documenting the code design through some sort of visualization? If so, using UML or something else? I suppose there might be tools for doing this automatically in some languages? Otherwise I think if it was valuable enough, it could be something we make sure to review and update along with code changes.
Any thoughts would be appreciated!
128 comments
[ 9.5 ms ] story [ 270 ms ] threadhttps://plantuml.com/
I'd say the big problem in visualizing big systems is that you can't usefully do it in one graph. For instance I worked on a system that had 2000+ database tables if you were going to make a diagram of that which shows everything it is going to take up a long wall. (This can be useful, but it is a big commitment)
A useful tool is going to let you make meaningful diagrams that show the subset of entities that are part of a story. I went to an art show of Mark Lombardi's works
https://en.wikipedia.org/wiki/Mark_Lombardi
who (before he was murdered) drew elaborate diagrams of conspiracies. One thing they showed was drafts that he made in the progress of creating his visualizations and he would sometimes make 40 or more of them. He would start out with a "hairball" that was disorganized and gradually figure out how to lay the diagram out in a way that made the meaning obvious.
I was blown away by the idea behind C4 when I first saw the presentation. I think what's missing is the tooling. I use C4 PlantUML do document my architecture designs.. what I'd really love though is a google maps style interface where I can zoom in or out of the current level I'm at. That'd be a game changer. Then you can really describe and understand the system.
The original presentation, in fact, used the google maps interface to illustrate the idea where you're first looking at a continent, then you zoom in to the city and finally the street level.
If you are using C4 right now, how do you compose the various level of architecture and navigate around them?
[0] https://news.ycombinator.com/item?id=31370268
That’s because it’s flat
Imo this changes the game
https://noda.io/
Imagine being able to make a fully 3D graph inside a space the size of a large building
https://github.com/whyboris/TypeScript-Call-Graph
Works for _functions_ not classes. I'm unsure how useful this tool is, but I suspect it might be helpful in some codebases.
Its called MTREES and its a free epub on Apple or Google.
https://mtrees.io
If you're looking to understand it's properties and how it behaves I would look into something more robust like Alloy 6 [0] which has a great visualization system for inspecting models. However if you're looking for a class diagram tool then it's outside your wheelhouse.
There's also something I've played around with a bit but haven't used seriously: Moose [1]. It's basically an IDE for doing analysis of code. The trick is writing good parsers.
[0] https://alloytools.org/alloy6.html
[1] https://moosetechnology.org/
In school, I was taught to draw UML for classes within a program. I have never seen that IRL. I think the difference is the time required to comprehend the application.
SoftVis3D (https://softvis3d.com/): where a "‘code city’ view provides a visualization for the hierarchical structure of the project".
Code Park: A New 3D Code Visualization Tool (2017) (https://arxiv.org/pdf/1708.02174.pdf), a “novel tool for visualizing codebases in a 3D game-like environment” with code represented as “code rooms” with code on the walls.
Code Structure Visualization Using 3D-Flythrough (2016) (https://opus-htw-aalen.bsz-bw.de/frontdoor/deliver/index/doc...), with spatial metaphors and first-person exploration of code.
Primitive (https://primitive.io/), a VR collaboration startup with a Matrix-looking “Immersive Development Environment” with “new tools for visually analyzing software in 3D”.
AppMap (https://appland.com/docs/how-to-use-appmap-diagrams.html), an automated code analysis tool that includes dependency maps and trace views.
plurid (https://github.com/plurid/plurid), a framework for visualizing and debugging code in a 3D explorable structure.
fsn (file manager) (https://en.wikipedia.org/wiki/Fsn_(file_manager)), an experimental application to view a file system in 3D (featured in Jurassic Park).
https://github.com/tikimcfee/LookAtThat : A macOS and iOS app to load, analyze, and walk around your Swift code, version 0.0.0-prealpha!
If that can't be done, there are some interesting things you can try. A lot of the suggestions in the thread are "top down" methods; you can get a lot of value out of "bottom up" visualizations too. Things like:
- Histograms of which lines / functions get called the most, or spent the most time in
- Which lines / functions / files get changed the most in the git history
- CPU flamegraphs
- Plain old print-debugging
In over-architected systems it can be difficult to figure out where the real "meat" of the code is, as opposed to the endless layers of configuration and wrappers and interfaces and indirection. UML diagrams may not help, or even be deceiving, but a stack trace never is.
I like the range of approaches in the Architecture of Open Source Applications books: http://aosabook.org/en/index.html
If you can, try to put together 2 different diagrams presenting different views. For example, sequence diagrams, model diagrams, etc. each tell you something different. Having a few different perspectives on the same system will give you a richer understanding.
Not specifically related to visualization, but, also, if you spend a lot of time trying to understand a piece of code, once you understand it, document it (e.g. in a function or method comment). Over time, this makes a huge difference and will help you and others out when you revisit the code later.
You could map the way programs fit into machines, and the networks between them. This would be the topology.
You can map the way services call upon one another with requests. This is the service graph.
You can map how systems interact over events or shared resources. You could say this is the logical graph.
The problem happens when you try and graph them all at once. It's the same as trying to draw a real map, with all the services, bus routes, railways, shops and administrative regions superimposed on one image. It's very busy.
So I use separate maps.
Tools are another matter. Personally I use Mermaid for graphs. I also have my own tools that create SVG visualisations using DAGre. This can be helpful for interactive visualisations where you can click into different nodes and explore more detail.
My system uses CloudFormation templates and our in house deployment DSLs to figure out the "topology", then let the users see the different superimposed "graphs" as they see fit
Also the C4 Model seems cool but I don't currently use it
https://c4model.com/
I have even used it to render infrastructure diagrams of actual production systems (clusters, load balancers, etc)
Please don’t be condescending and incorrect.
So you need to break it down into multiple documents that cover different use cases and include only the components for a small set of use cases.
Then use the C4 model to break up the docs.
I use https://mermaid-js.github.io/mermaid/#/ for the diagram itself because Github natively supports it in markdown files, so you can revision control the diagram. I managed to get reasonably close to the C4 diagrams minus a few features that mermaid does not support.
The suggestion it made was to look across module boundaries or microservice boundaries, while making a particular request. So I go to update a Project with a new Pipeline, and I find out that the project service talks to the pipeline service which then has to create resources for which it talks to various resource services, all of that.
Since there aren't great digital tools for doing this, for visualizing these things, it was suggested in that talk that one of the more outside the box things you could do is to just take cardboard and modeling clay and strings and cut out some shapes to represent the different services, let each string be an RPC, and the actual diagram you would imagine being alive in time, like little beads flying across these strings, to indicate requests going out and then responses coming back... But the key was less to witness the time but more to get a timeless sense of connection, “oh, it turns out ResourceService is very hairy in these diagrams, it is kind of the central hub for this microservice cluster.” and for that it was helpful that the visualization had a certain physicality to it, it had weight and structure and engaged more senses than just the visual...
I've actually thought about just digitizing these ideas, even though it misses half the point LOL. I think that could be some wonderful documentation and diagrams in our onboarding for new folks.
Most APM/distributed tracing products have ways of visualising distributed traces so we can see starting from a specific call which services were involved and how much time is spent in important operations (e.g. db, etc). Here's an example: https://www.datadoghq.com/product/apm/#end-to-end-tracing
Datadog builds this service map automatically for you from APM and RUM data: https://docs.datadoghq.com/tracing/visualization/services_ma...
AFAIK you can consume the data via API so you can build other visualisations on top of it if you don't want to stick with the flame chart or service map.
Since this is runtime information it won't be as comprehensive as static code analysis but it does show what's actually happening in the system.
disclaimer: I work for Datadog edit: add link to service map
a metacomputer of sorts; maybe epicomputer would be a better name?
I don't know if an automated visualization system is possible, but you'll have to understand the whole thing before doing so. Pen and paper was the most expedient solution for me at the time.
I remember a whole bunch of light bulb moments when I showed other developers the "big picture". It's an awesome technique when you're forced to work on spaghetti!
https://www.youtube.com/watch?v=_nTpsv9PNqo
Could do similar with bash text mangling tools, but language native would probably be best.
I dunno, just a thought in an EOD fog. I don’t own a printer these days, so I guess I’d need an alternative.
Tell computer to observe self and report back.
What I generally do, is start with what I call a "napkin sketch" (which can be UML-ish)[1], and try to avoid writing down too much stuff, in order to reduce "concrete galoshes"[2].
I try to use tools like Doxygen and Jazzy, to document the code, in an inline fashion[3]. Doxygen will generate a UML "Lite" diagram[4].
[0] https://littlegreenviper.com/miscellany/swiftwater/the-curio...
[1] https://littlegreenviper.com/miscellany/forensic-design-docu...
[2] https://littlegreenviper.com/miscellany/concrete-galoshes/
[3] https://littlegreenviper.com/miscellany/leaving-a-legacy/
[4] https://doxygen.nl/manual/diagrams.html
And, tangently related, visualizing concurrency: https://divan.dev/posts/go_concurrency_visualize/
There is however a growing movement of being able to visualize how a system is functioning at various levels. XState/Statecharts are a good example (https://xstate.js.org/viz/). Another example in the Ops space would be https://github.com/spekt8/spekt8 for K8S. I work at Grafana and we're more or less trying to expose these things in ways that make sense. Our bread and butter is timeseries data but we're adding more in that regard (it's possible to build node graphs from running systems).