OOPSLA 2001 Software Archeology Workshop
Position Paper
Dragos A. Manolescu
Applied Reasoning and the University of Kansas
dragos.manolescu@acm.org
At the beginning of the year I have worked as framework architect on a large project. The project—a J2EE eBusiness application—involved several third-party products (TopLink, WebLogic) and Java frameworks for presentation, stateful Internet application, object persistence, and customer profile from Applied Reasoning. At the end of my assignment, we had 713 Java classes, 178 interfaces, and 8829 methods.
My goals were twofold. First, push framework evolution forward and take Applied Reasoning’s frameworks through another iteration. Second, help the client’s developers understand the frameworks and the application. Naturally, the second objective required my having a good grip of the application and frameworks.
After a quick overview of the business (i.e., what does the system do?) I explored a cross-section through building a small application. I paired up with one of the original framework developers: I was “driving” while he was guiding and answering questions. I started from the presentation layer and made my way through to the persistence. When I hit the persistence layer I took a one-day sabbatical to work with the developer of the persistence framework, who was off site. I wound up with a complete (albeit very simple) application. The exercise gave me first-hand experience with all layers, from presentation to persistence. It provided me with a sketch of what the eBusiness application has under the hood.
Next, to understand the application as well as how the different pieces fit together, I started decomposing it into smaller pieces (divide and conquer). Architectural and design patterns provided the means of describing these pieces succinctly and precisely. They also provided information about why the framework developer has chosen one solution against another. This revealed interesting assumptions, some of which turned out to be wrong.
First I divided the architecture into four logical layers: presentation, session, application, and service—the Layered Architecture architectural pattern. Within each layer, design patterns like Manager, Property, Abstract Factory, Template Method, and Model-View-Presenter helped me bring more order to the picture. Figure 1 shows the type of diagram I’ve subsequently used to give developers a bird’s eye view.

Figure 1: System diagram
Then I paired up with application developers to understand better the parts of the system they were working on. I’ve also used these sessions to take note of the parts that they had a hard time understanding. Subsequently I refactored these parts based on their feedback. This provided additional insight about the system. One of the most common refactorings towards making the whole system easier to understand was renaming. For example, the original system had two methods for handling page display (with JSP technology): processFirst for opening the page in the browser, and processEvents for handling form submission. Changing these names to processOnOpen and processOnSubmit made it clear when they were called.
Writing JUnit tests also helped me understand how things worked. The system had no unit tests when I joined the project. Adding tests gave me an opportunity to take a closer look at the internals on my own, and do additional refactoring.
Finally, I’ve run several architectural overviews together with the chief architect. Preparing for these sessions and answering developers’ questions turned out to be a very useful exercise in understanding the system.
Cutting a cross section and exploring the parts exposed by the cut through writing code provides a big step towards understanding a large system. Ideally you would do this along with someone who knows the system (the original framework developers in my case). It’s hard to think of a better way of understanding something than actually doing it! Once you emerge from darkness and start to distinguish contours, simplifying what you see, compressing it, and/or translating it into familiar things (for example, with patterns) helps you keep complexity under control. Pairing up with developers who know their way around lets you dig deeper in the parts of the system that are still in the dark.
Notice that the above requires being around people who either know the system (like the original developers) or are comfortable with the parts that they use (like the application developers). I’d be interested to explore how the availability of these resources affects the understanding process.