Code-to-UML Mapping Examples

Chapter 5 - Reverse Engineering
byAndrew Filevet al.?
Wrox Press ©2002
Team FLY

In this section we'll look at the mapping between common code constructs and the corresponding UML notation. Each example will be in the context of the ParcelTracker sample application, so you'll be able to look for yourselves at the original code in Visual Studio .NET and the resulting UML in Visio.

All of the examples originate in C# code, which is not to imply that you must use this language. Unlike code generation, which results in a single UML concept being mapped to a slightly different code construct in each language, reverse engineering maps code constructs of the supported language - C#, Visual Basic .NET or C++.NET in our case - back to a single UML representation. In other words, although member variable declarations look different in C# and Visual Basic .NET the resulting UML attribute looks the same when reverse engineered.

The information presented here is intended to whet your appetite for looking deeper into the mapping between various code constructs and their UML representations; which you can do simply by coding a few classes in a Visual Studio .NET and looking and the reverse engineered results in Visio.

Generalization (or Inheritance)

The ParcelTracker_Data0bjects project includes a class called DeliveryDataSet (in the namespace ParcelTracker_DataObjects) that inherits from the .NET System.Data.DataSet class. In code, the class definition is the following:

     namespace ParcelTracker_DataObjects     {        ...        public class DeliveryDataSet : DataSet        { 

The reverse engineered model contains a DeliveryDataSet class (in the package ParcelTracker_DataObjects) and a DataSet class (in the package System | Data). Simply dragging those two classes onto a static structure diagram produces the following result:

click to expand

First you'll notice that a generalization (or inheritance) relationship has been drawn automatically between the two classes to show that DeliveryDataSet inherits from DataSet. I did not draw that in myself, it was already present in the reverse engineered model as a result of the inheritance between the two classes in code.

The second thing you'll notice is that the DeliveryDataSet is fully populated with attributes and operations whereas the DataSet is not. That's because the first class is defined in the solution that we've reverse engineered, whereas the second class is simply referenced via the inheritance in code. This is yet another illustration of the fact that the .NET Framework classes that are only referenced and not defined in the application will be reverse engineered into the resulting UML model by name only.

If you want to look into the code of the DeliveryDataSet class in Visual Studio .NET, you'll find that at first glance there is no source code file for it. That's because this class was not hand-coded but was auto-generated from an XML schema during the application design. To investigate the code, you can switch to the Class View in the IDE and click the DeliveryDataSet class as shown here:

click to expand

Associations and Attributes

The following figure once again shows the DeliveryDataset class from the previous example, this time combined on a static structure diagram with the DataManager class.

click to expand

I can tell you that when I designed this application originally - using Visio for Enterprise Architects - I had an association drawn between the DataManager and DeliveryDataSet classes, yet in my figure (above) no association is shown between the reverse engineered classes. To see what I mean take a look at my original static structure diagram below, which was used to generate the application code initially according to the process described in Chapter 4.

click to expand

This reinforces the point we made earlier that a reverse-engineered model in Visio has no static structure diagrams initially, and in Visio no diagrams means no associations.

In contrast, a Rational XDE reverse engineered model would show an association between the DataManager and DeliveryDataSet classes as you can see here:

click to expand

For the Visual Studio .NET and Visio combination we have seen here that reverse engineering is not an exact reversal of code generation. But no information has been lost in the sense that during code generation the association was mapped in code to a member variable of the DataManager class (-deliveryData : DeliveryDataSet), which is shown in the UML diagram and which corresponds with this code:

     public class DeliveryManager : MarshalByRefObject      {        private DataManager dataManager; 

UML attributes are used therefore as an indication of associations between two classes, in the case that the type of an attribute is that of another class in the model. I can see why it makes sense to retain attribute representations of member variables, but not assume them to be associations, because otherwise it's difficult to see where the line should be drawn.

Given the following reverse engineered class definition in Visio, should the attribute -deliveryDataGrid : DataGrid be drawn automatically as an association between our DeliveryDataForm class and the .NET Framework DataGrid class?

click to expand

Maybe not, because I'd like to treat .NET Framework classes - particularly classes like String - as fundamental types just as if the attribute type was a true fundamental type like int or bool, or even string (with no initial capital).

In my C# Today article "C# to UML Reverse Engineering" (http://www.csharptoday.com/content.asp?id=1837) I described a technique for reverse engineering a .NET assembly into a Rational Rose model. I chose to model a source code member variable as a simple attribute if the type was a fundamental C# type or a .NET Framework class, otherwise as an association to another class in the model. This was a halfway house between Visual Studio .NET and Visio (which maps all member variables to simple attributes) and Rational XDE (which forms associations for all member variables not of fundamental types).

Regardless of whether the attribute represents a fundamental data element or an association, the Visio rendering will show the attribute preceded by -, +, or # according to whether the member variable was private, public, or protected.

Operations and Properties

In simple terms, operations - or methods - in code map to the operations of a class in UML, modified with a -, +, or # for the visibility and underlined if they are static, like this:

click to expand

which corresponds to the code:

     class StartServer     {         [STAThread]         static void Main(string[] args)         { 

But not all operations are the same; in Visio Enterprise Architect, an object property is also modeled as an operation. Looking back at the representation of the DataManager class (reproduced below) you may be surprised to learn that the DeliveryDataSet () operation actually represents a property. Surprised because there's nothing in that representation that explicitly marks it out as such.

click to expand

So how do I know that it's a property? Firstly, I know because I wrote the code and it looks like this!

     public class DataManager     {         private DeliveryDataSet deliveryData;         ...         public DeliveryDataSet DeliveryDataSet         {             get { return deliveryData; }         }     } 

Secondly I know because I can double-click the class in Visio, select the Operations category, click the DeliveryDataSet operation and press the Properties button, and then select the Code Generation Options category to give this dialog:

click to expand

As you can see here, the operation has Kind set to Property and the Create Get Method option is checked. Looking back at the code above confirms that this operation does indeed have a get() method but no set() method.

Operations will normally have their Kind marked as Procedure. They may also be marked as Property (as you have seen), Constructor, Destructor, Event, Indexer, or Operator depending on what kind of code construct has been reverse engineered to yield the operation.

It's interesting to compare the Visio representation of properties with the Rational XDE representation shown earlier. In XDE the property is rendered as a combination of an attribute with <<property>> stereotype and an operation with <<get>> stereotype.

Method Bodies

As we saw in the last chapter on the UML Operation Properties dialog you can click the Method entry and actually insert prototype code as the implementation for the operation.

click to expand

By pressing the Preview Code button in the UML Operation Properties (Code Generation Options) dialog you can then see that during code generation your prototype code - in this case just a comment - will be inserted into the body of the operation.

     // Preview of code that will be generated in the implementation file:     public string getStatus(string deliveryNumber)     {         // Here is my method implementation     } 

As we're not dealing with code generation here, why am I telling you this? Well, I was hoping that this would work in reverse so that each reverse engineered operation would be populated with the implementing code. Sadly, no, so maybe that's one for the wish list.

Primitive and Value Types

For each of the primitive or value types for the Visual Studio .NET languages, there is a corresponding Visio UML type, pre-built into any Visio UML model as shown here:

click to expand

Those pre-populated types are useful, but not sufficient in themselves; which is why it is necessary for the reverse engineer to incorporate referenced classes in a model, at least by name, and also why a base .NET Framework model (discussed later) would be so valuable.

Team FLY


Professional UML with Visual Studio. NET. Unmasking Visio for Enterprise Architects
Professional UML with Visual Studio. NET. Unmasking Visio for Enterprise Architects
ISBN: 1440490856
EAN: N/A
Year: 2001
Pages: 85

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net