Model/Code Synchronicity: The UML Holy Grail --- found at last?

 

By Doug Rosenberg
www.iconixsw.com

 

 

Mind the reality gap

Since the beginning of modeling time, the gap (sometimes a chasm) between models and code has always been problematic. Models, the argument goes, don’t represent reality…only the code represents reality…therefore the model must be worthless, and we should just skip modeling and jump straight to code. Those who have used this argument to avoid modeling probably felt quite safe in doing so because nobody has ever managed to make “reverse engineering” or “round-trip engineering” a very seamless process…until now. The innocuously named “MDG Integration” product from Sparx Systems (a companion product to the Enterprise Architect modeling tool) changes the whole equation.

 

Bringing Mohammed to the mountain

You can lead some programmers to UML, but you can’t make them embrace modeling. The ever-present gap between models and code is one of the reasons for this. Modeling introduces another environment, another tools interface, another user interface to learn, and forces the programmer to leave the familiar confines of their coding environment, where they have all the comforts of home. In short, it’s often viewed as a pain-in-the-neck.

But what would happen if the UML model was brought inside of the programming environment? Let’s say if you could open your project, right click a menu and say something like “Attach UML Model”. So you can browse your use cases, sequence diagrams, classes, etc. from within, let’s say, Visual Studio 2005 (Eclipse is coming in a few months, but not ready yet). OK so far? Then let’s suppose you could “hot link” a package of classes from the UML window to the source code. Nice, but not compelling yet? How’s this? You can double-click on an operation on a class in the UML window and instantly browse to the source code for that method, and you can edit the code as you normally would in Visual Studio 2005 and update the UML model by right-clicking on the class and choosing “Synchronize”.

Suddenly, instead of the UML model being a pain-in-the-neck, the model is actually helping you to navigate through your code, you can click to see the use cases and sequence diagrams that are using the classes you’re building, and you can re-synch the models effortlessly. Suddenly your UML model is the asset which it was supposed to be all along.

Gosh, it sounds so…agile...is it really that easy?

We don’t blame you for being skeptical, so we’d like to use the remainder of this article to show you an example. If you’ve seen our book, “Agile Development with ICONIX Process” (Apress, 2005), or if you’ve been to one of our open-enrollment public classes, the example might be familiar to you.It’s a C# /.Net application, modeled in Enterprise Architect using ICONIX Process, and developed in Visual Studio.

The application is a map-based hotel finder (we call it the “mapplet”) that’s in production use on the VResorts.com travel website, and the design, from use cases through C# code, is presented in the Agile/ICONIX book.

 

You can compare the use cases in the book to the running application, live on the web, and you can look at the C# code that makes it work, either in the book, or inside Visual Studio.In fact you can browse the C# code using the UML model.

A quick example of driving a use case to code

This example is borrowed from our book “Agile Development with ICONIX Process”.It shows a use case for filtering the hotel display by amenities and by hotel chain, it’s robustness diagram (you can see the sequence diagram at the top of this article) and some classes which are needed to implement the use case.

 

Filter By Amenity:

The system displays the List of Amenities in the Amenity List. The user selects one or more amenities from the list and then selects Update Map. The MapViewer creates a HotelFilter based on the selected items in the Amenity List. The MapViewer queries the HotelServer for all hotels in the AOI and then filters the results with the HotelFilter. The map is refreshed and a label is placed adjacent to the map indicating the current selection criterion.

Filter by Hotel Chain:

The system populates a Hotel Chain pick list from the Hotel Chain table. The user selects one Hotel Chain from the pick list. The MapViewer creates a HotelFilter for the selected Hotel Chain. The MapViewer queries the HotelServer for all hotels in the AOI and then filters the results with the HotelFilter. The map is refreshed and a label is placed adjacent to the map indicating the Hotel Chain selected.

Alternate Scenario 1:

If there are no Hotels that meet the filter criterion, the following message is displayed: “No hotels meet selection criterion. Please expand search.”

Here’s the robustness diagram for this use case:


 

And here are some classes:

 

 

Finally, here’s some C# code for the HotelFilter class:

 

public class HotelFilter

{

private string AmenityFilter;

private string HotelChainFilter;

private string HotelChainName;

private AmenityList Amenities;

private char [] delimiter;

 

public HotelFilter(AmenityList aAmenities,

string aAmenityFilter,

string aHotelChainFilter,

string aHotelChainName)

{

Amenities = aAmenities;

AmenityFilter = aAmenityFilter;

HotelChainFilter = aHotelChainFilter;

HotelChainName = aHotelChainName;

 

string delimStr = " ";

delimiter = delimStr.ToCharArray();

}

 

 

public string GetFilterText ()

{

if (HotelChainFilter.Length > 0)

return "Currently displaying " + HotelChainName;

if (AmenityFilter.Length > 0)

{

string res = "";

AmenityItem p;

for (int j = 0; j < Amenities.count; j++)

{

p = Amenities.data [j];

if (p.abbr != null)

if (AmenityFilter.IndexOf (p.abbr) >= 0)

{

if (res.Length > 120)

{

res = res + ", ...";

break;

}

if (res.Length > 0) res = res + ", ";

res = res + p.val;

}

}

return "Currently displaying hotels with " + res;

}

return "";

}

 

 

public bool FilterHotel (string aHotelChain,

string Amenity,

ref string hotelAmenities)

{

string [] sp;

AmenityItem p;

 

if (HotelChainFilter.Length > 0)

return HotelChainFilter.ToUpper ().

Equals (aHotelChain.ToUpper ());

else if (AmenityFilter.Length > 0)

{

sp = Amenity.Split (delimiter);

hotelAmenities = "";

for (int j = 0; j < sp.Length; j++)

{

p = Amenities.Find (sp [j]);

if (p != null)

hotelAmenities = hotelAmenities + p.abbr;

}

 

for (int j = 0; j < AmenityFilter.Length; j++)

{

if (hotelAmenities.IndexOf

(AmenityFilter.Substring (j, 1)) < 0)

return false;

}

}

return true;

}

 

}

 

Nice and simple so far. Any child could do it.As one of my old Electrical Engineering professors used to say (I think we were studying Maxwell’s Laws at the time): “It’s intuitively obvious to the casual observer”.

 

But…here’s the six million dollar question:how do we keep the model and the code synchronized over the lifetime of the project?

Five Simple Steps to Modeling Nirvana – without chanting OMMMMM

 

We wrote a whole chapter in Agile Development with ICONIX Process about how to synchronize models and code, and the reasons why it’s important.It’s still just as important, but the folks at Sparx Systems have obsoleted the “how-to” from that chapter. Now it’s absurdly simple. So simple that an old tool-builder like me wonders “why the heck didn’t I think of that?”

 

Here’s how it works:

 

1. Connect UML model to VS 2005 Project
2. Link package in model to VS project
3. Browse source code by clicking on operations on classes
4. Edit source code in VS
5. Right-click on class and choose Code Services -> Synchronize

Let’s take these one at a time:

 

Connect the UML Model to the Visual Studio 2005 Project

When MDG Integration is installed, Visual Studio 2005 gains the ability to have a UML model attached to it. You do this by selecting “Attach UML Model”from the Visual Studio Solution Explorer:


Link package in UML model to the Visual Studio Project

 

Visual Studio 2005 and Enterprise Architect are advised that the classes within a certain package should be hot-linked to source code files in VS.

 

Enterprise Architect then reverse engineers the code for you, automagically.

 

 

Browse source code by clicking on operations on classes

Your UML model should provide high-level guidance and help you to understand how the code is structured. Hopefully, modeling the system in UML resulted in cleaner, better organized code. What could be a more natural way to leverage the investment in the UML model than to simply click an operation on a class in the UML browser window, and have Visual Studio pop up the associated code?

 

If there’s a more natural way to browse your source code and maintain a high-level view of the code’s organization, we haven’t seen it.

Edit source code in Visual Studio

Actually you can either edit the source in Visual Studio, or edit the operations in the UML browser…

 

 

Right-click on a class and choose Code Services -> Synchronize

You’ve added some detail (revised parameter list, maybe) to a class in EA, or you’ve edited the code in Visual Studio.Now you need to confront the ever-so-painful task of synchronizing the model and the code. Ever the good agilist, you’ve read Scott Ambler’s writings on the subject and for years have practiced “Update only when it hurts” because this task has been so difficult. Then your models and your code have gotten out of synch and you’ve gradually disregarded the models. But, you think to yourself, what if the UML and the code were really one and the same. Just two representations of the same thing…the UML classes and the C# classes united by their inner-oneness and sameness of purpose. What would it be like? So you right click on the class you just modified and select “Code-Services -> Synchronize”. Ahhhhhh…..nirvana at last.

 

Would you like some project documentation to go with that code?

Oh, we almost forgot. Do you have annoying managers who ask you to document your stuff? EA handles that for you, too…in your choice of RTF or HTML.

 

No worries, mate! The documentation gets automagically done for you! Life is good.

 


© ICONIX Software Engineering, Inc. 2016
11301 W Olympic Blvd., Suite 559, Los Angeles, CA 90064
Tel (310) 474-8482