I've mostly only had to read my own code. As such, I've had no need to visualize the code as I already know how each and every class and module communicate with one another.

But the few times I've had to read someone else's code - let us now assume we are talking about at least one larger module which contains several internal classes - I've almost always found myself wishing "This would have been so much easier to understand if I could just visualize it!"

So what are the common methods or tools for enabling this? Which do you use, and why do you prefer them over the others? I've heard stuff like UML, module and class diagrams, but I imagine there are more. Furthermore, any of these is most likely better than anything I can devise on my own.

EDIT: For those who answer with "Use pen and paper and just draw it": This isn't very helpful unless you explain this further. What exactly am I supposed to draw? A box for each class? Should I include the public methods? What about its fields? How should I draw connections that explain how one class uses another? What about modules? What if the language isn't object-oriented but functional or logical, or even just imperative (C, for instance)? What about global variables and functions? Is there an already-standardized way of drawing this, or do I need to think up of a method of my own? You get the drift.

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
If this question can be reworded to fit the rules in the help center, please edit the question.

1

If you can vote and think this is a useful question or it have useful answers below, please vote up. StackExchange sites need votes to build a good community. You can give 30 votes per day, don't waste them. Specially users with high reputation and low counting votes given please read this: meta.programmers.stackexchange.com/questions/393/…
–
bigownOct 5 '10 at 22:30

1

Learn UML and you will know what to draw with pen and paper.
–
mouvicielOct 6 '10 at 12:41

1

I have been in your situation, and have found UML vry useful - just because it explicitly states what you draw uml.org
–
yati sagadeDec 24 '11 at 18:55

18 Answers
18

I like to use NDepend to reverse engineer complex .NET code base. The tool comes with several great visualization features like:
There are dozens of way to visualize a code base, and to complete the Pierre_303 answer, here are a bit of screenshot extracted from NDepend (disclaimer, I am the creator of NDepend).

Dependency Matrix: It represent the same information as a Graph but in a complete different way. Matrix is better than Graph to displays large dependencies set with hundreds of nodes and edges, while Graph are better than Matrix for smaller dependencies set, especially with less than 20 nodes. Matrix has also he immense advantage to show code structural pattern at a glance, like layered code, dependency cycle, cohesion, coupling... More info here.

Code metric visualization through treemaping: This not aims at showing code structure/architecture but more how the code is partitionned. Here rectangles shows methods, classes and namespaces, and the more lines of code a class has, the bigger its rectangle is. By choosing an appropriate combination of code metric and level values, the Treemap Metric View helps see patterns that would be hard to spot with other ways. More info here.

It whatever way you best understand it. If you are a visual thinker, how would draw code that you can visualize? For myself, i sketch out flow charts, or database diagrams/UML. once you have a way of representing the code, try reading through the existing code and sketching it out as you read throught it.

+1 For me nothing beats pen and paper. I read through the code and sketch out diagrams as I go along. The mechanical process of drawing it out yourself helps to understand and remember things better.
–
ysolikOct 5 '10 at 21:11

3

totally agree, using pen and paper is the best, doing diagrams on the computer is just distracting until you understand what you're actually drawing.
–
Sam JOct 5 '10 at 21:15

3

OP asked about more detail for drawing - I have used 3" x 5" cards (AKA recipe cards) for visualizing large systems. I write down the names of the classes and make some annotations on the cards and arrange them as I see fit to show how they work together. Once I have a vague idea that I understand it I try to explain it to someone else. Oddly, the LESS they know about software the MORE useful it is to me, because I have to explain my assumptions. Other paper is good for making notes. Being away from the editor / debugger is a good way to keep things in focus and concentrate.
–
Todd WilliamsonOct 6 '10 at 2:12

If the code is split into layers, then you can easily visualize code by simply drawing the layers in detail.

Lets take android for example:

Now this is the more common type of diagram thats really easy to draw. To make it useful to you however, just start drawing lines to represent the flow of data. In this example you could trace an application to XMPP to SSL to the bluetooth driver, or any other combination.

I would recommend though that you go a bit more in depth. Since most projects aren't as large as Android, you can make things a bit simpler and have each box be a class or a method which makes it easier to actually write the code later.

Also, take a look at Ward Cunningham's Signature Survey. It is lightweight and simple, but surprisingly useful to get a feel for the size and complexity of parts of the codebase.

He originally did it for Java, but you can always adapt it for the language you're working in. I recently did it with VB (while making a few additions of my own) and it has been very helpful. Here's a sample of what the output looks like:

UML class diagrams for structure and sequence diagrams for behavior (UML offers more diagram types for these two purposes, all focusing on different aspects of the software - these are the two I find particularly useful and I do sketch/generate them when needed because they help a lot).

NDepend is a Visual Studio tool to manage complex .NET code and achieve high Code Quality. With NDepend, software quality can be measured using Code Metrics, visualized using Graphs and Treemaps, and enforced using standard and custom Rules.

Hence the software design becomes concrete, code reviews are effective, large refactoring are easy and evolution is mastered.

If there are too many classes all talking to each other I draw them as boxes and draw lines/arrows between them to see who talks to who.

If there are nested function calls and I need to figure out who depends on who I do something similar to sequence diagrams.

When it comes to the logic itself, I do two things. One is I imagine the data layout and follow in my head the way it is manipulated while the code runs, and two is I build a "mental image" of the logic. What this mental image is I really can't explain because I do not actually envision it, more like feel its "spatial quality" much in the same way that imagining a map helps you figure out your surrounding.

If you're using Java or Smalltalk, you should definitely check out Code City. It lets you use the part of your brain that is familiar with navigating cities to instantly get a whole new perspective on your codebase! It certainly blew my mind when I first used it.

If you have a good debugger, and are good at using it, you can step into code, breakpoint it, hover over objects and see their state, etc. Essentially, you walk through the code as it is executing. I find that this helps me mentally stitch together the various objects, and how they are interacting with each other.

But also, the question is too generic to get a good reply. What language is the code in. If it is something statically typed, etc like Java, there are tools to parse/convert/visualize the class structure, cross-links, etc. If it is more dynamic like Ruby, you may have a lot more troubles.

If it is public domain, often there are sites that specialize in searching and navigating through the code. Linux certainly has one, as an example.

Also, can you run the code or can you only read it? If you can run it then try sticking a thread dump (or non-Java equivalent) into the locations you are confused about. That will show you what path the program took to get there. If you have trouble understanding which configuration files are loaded and when look at something like ProcessMonitor from Sysinternals/Microsoft. For network behavior analysis, you may use Wireshark. In general, you can use troubleshooting techniques. For Java, I did a presentation on that a while ago for JavaOne/InfoQ: http://www.infoq.com/presentations/maintaining-production-java-apps

Finally, try searching for Source Code Analysis tools, often they include visualization components.

Not quite visualizing, but I find going through different use cases a really helpful way to visualize how different classes are interacting. This is especially helpful when you've got lots of little classes and it can be overwhelming to try and understand them all together.

Write a test that will start your use case and fire up the debugger, and then draw the flow of class interactions. This is especially helpful when you're going beyond your single project as you can see which other projects are being utilized. Depending on the complexity, a state diagram would do the trick.

AgileJ StructureViews is built for exactly the situation you describe - wanting a visual version of a large codebase written by other people. The usual problem with reverse engineered UML class diagrams is that the results contain so much detail that you are not much better off than just reading the code. AgileJ is big on filtering. Below the class diagram is a filter script which you edit to cut down the members which are displayed. AgileJ is also big on batch diagram generation. You can kick off a batch and it will look for groups of related classes to form diagrams which you can browse to see the structure.

When you´re coding, you get the needs from a complete view and you breaks into small pieces and starts sketching, diagraming and coding. After this, you joins the parts and has the complete result.

For understand code not created by you, the same process must be made. In this process you can use diagrams if you have. Start with use cases, component and sub-system view and finish with class diagrams where your focus is logical view to understand relations and responsabilities, not attribute/methods.

After that, you start investigate detailed class diagrams or goes direct to the code. I think sequencial diagrams are little confuse, I prefer to look at the code.

I think that UML is not a ideal form yet, but it is a standard that many people knows and is easy to share and understand.

If you not have a UML documentation, you can use reverse engineering, but you will need help to figure out some things.

I use EclipseUML Omondo for navigating in the code at model level. Really cool !!
I first reverse my java project in order to map it to the UML model. Then I create views of my model by detecting associations, dependencies, inheritances etc... show and hide what I need. I can create as many diagram as I need based on a single model which is mapped to Java.

The trick Omondo uses is to map Java and UML ids and synchronize it directly to the UML metamodel. Marvelous technology and really amazing to visualize my code.