This article, the third in a series of articles introducing the concepts of
object-oriented design and the Unified Modeling Language (UML), continues
the study of modeling class structures using UML notation and the class
diagram. My focus here is on the modeling of class hierarchies, which are
common to most class library applications. I will use Visio to create the
UML class hierarchical structure. I will also examine Visio's code
generation to verify the class model against the .NET code necessary to
create the library.
Modeling Class Inheritance
Class structures are fundamental to any object-oriented programming
language. The class structure is a template for the objects that will
implement the functionality of your applications. As a .NET developer, you
need to become increasingly familiar with the classes available in the .NET
Framework. As you gain experience developing .NET applications, you will
discover the need to develop your own class libraries. Good design of
object-oriented applications dictates a clear separation of functionality
between the user interface, business logic, and data access logic.
Well-designed applications achieve this separation of functionality through
the development of class libraries that encapsulate internal processing. By
developing class libraries, your applications become more manageable,
scalable, and extendable.
One of the most powerful features of object-oriented programming
languages is the ability to create class hierarchal structures. Using class
hierarchies and inheritance allows the programmer to create base classes
that encapsulate common functionality. Classes that need to incorporate the
functionality simply inherit from the base class. The derived classes can
then implement the base functionality as is or augment it by overriding the
base class methods.
The .NET Framework contains numerous examples of inheritance. For
example, when creating controls, certain functionality is required for all
controls hosted on a form. A base Control class encapsulates this
functionality. For example, the Control class defines the BackColor property
and the BringToFront method. A ButtonBase class inherits from the Control
class and encapsulates functionality required by all types of button
controls. The Button, CheckBox, and RadioButton inherit from the ButtonBase
class and include specific functionality required for each control.
When modeling classes using UML, an arrow points from the derived class
to the base class. Figure 1 demonstrates how the button control class
hierarchy is represented in a UML class diagram. It is worth noting that
.NET supports only single inheritance. This means that a class can inherit
directly from only one base class. A single base class can, however, be
inherited by multiple derived classes.
When constructing base classes, decisions have to be made as to how the
class will be utilized in the class library. Will clients need to
instantiate and work with a base class directly, or will its functionality
be accessible only through derived classes (an abstract base class)? Are the
properties and methods exposed to classes (public scope), derived classes
(protected scope), or not exposed at all (private scope)? Do we force
derived classes to utilize the implementation of the properties and methods
or give them the ability to alter the body of a property or method
(Overridable)? Should clients of the class library be able to derive classes
from library classes, or should we limit the inheritance by sealing the
derived class (NotInheritable)?
As you build larger and more complex libraries that programmers
throughout your organization utilize, accurately modeling the structure of
your libraries becomes crucial. Additionally, programmers need documentation
outlining the structure and functionality of the class library to
effectively utilize and incorporate it in their programs. This is where the
UML class diagram fits in. It is an excellent tool for both modeling and
documenting class libraries.
Using Visio to Model Inheritance in a Class Diagram
The following activities will introduce you to the process of modeling
class hierarchies using a UML class diagram and Visio.
1. Start up Visio. From the File menu, choose New > Software > UML
Model Diagram.
2. Locate the Shapes window on the left side of the screen. This window
includes a tab for the common UML diagrams. Select the UML Static Structure
tab (see Figure 2).
3. From the Shapes window click and drag the Class shape onto the design
surface. Right-click the Class shape on the design surface and choose
Properties. A UML Class Properties window becomes visible (see Figure 3).
Change the name to "BaseClass". Add another class, named "DerivedClass", to
your diagram.
4. Right-click the BaseClass shape on the design surface and choose
Properties. The three check boxes IsRoot, IsLeaf, and IsAbstract determine
how the class functions in the class hierarchy. By checking the IsRoot check
box, you are restricting the class from inheriting from other classes.
Checking IsAbstract restricts the class from being instantiated, and forces
clients to instantiate a derived class to access the functionality of the
class. Checking IsLeaf indicates that the class is sealed. Sealed classes
are noninheritable and help to limit the depth of an inheritance chain.
5. Check the IsAbstract check box and select the Code Generation Options
in the Categories list box located on the left side of the UML Class
Properties window. Select Visual Basic in the Target Language dropdown.
Select default in the Implementation dropdown. Click on the Preview code
button at the bottom of the window. In the Code Preview window notice that
the keyword MustInherit is contained in the class definition code. This
restricts the class from being instantiated. Close the Code Preview window.
6. In the UML Class Properties window, check the IsRoot check box. This
restricts the base class from inheriting from other classes. Note: This does
not correlate to a keyword for code generation and the restriction is only
enforced in your Visio diagram.
7. In the UML Class Properties window, select Attributes in the
Categories list box. Click the New button to create a new attribute. Change
the Type to VB::Integer and Visibility to private. Add another attribute of
type VB::String and a visibility of protected. Private scope means it is
accessible only from within the class. Protected scoping is accessible from
derived classes. Public scoping is accessible from any class.
8. In the UML Class Properties window, select Operations in the
Categories list box. Click the New button to create a new operation. Change
the ReturnType to VB::Boolean and the Visibility to protected. Mark the
operation as overridable by checking the Polymorphic check box. Select the
Code Generation Options in the Categories list box located on the left side
of the UML Class Properties window. Select Visual Basic in the Target
Language dropdown. Select default in the Implementation dropdown. Click on
the Preview code button at the bottom of the window. In the Code Preview
window notice that the keyword Overridable is contained in the operation's
definition code. This allows inherited classes to alter the method
implementation if needed. Close the Code Preview window.
9. In the Shapes window, located on the left side of the screen, select
the UML Static Structure tab (see Figure 2). Click and drag the Generalizes
shape on the design surface. Attach the tail of the arrow (Generalizes
shape) to the DerivedClass shape. Attach the head to the BaseClass shape
(see Figure 4).
10. Right-click the DerivedClass shape on the design surface and choose
Properties. Select the Code Generation Options in the Categories list box
located on the left side of the UML Class Properties window. Select Visual
Basic in the Target Language dropdown. Select default in the Implementation
dropdown. Click on the Preview code button at the bottom of the window. In
the Code Preview window notice that the code includes an Inherits statement.
Close the Code Preview window.
11. Select Class in the Categories list box located on the left side of
the UML Class Properties window. Check the IsLeaf check box. Click on the
Code Generation Options and launch the Code Preview window. Notice that the
keyword NotInheritable has been added to the class definition. This seals
the class so that other classes cannot inherit from it. Close the Code
Preview window.
12. Select Operations in the Categories list box located on the left side
of the UML Class Properties window. Click on the Methods button on the right
side of the window. In the Operation name dropdown you can choose a base
class operation to override. Choose BaseClass::operation1. To override the
method implemented in the base class, click the Has Method check box. Click
OK to close the UML Method Properties window. Preview the code for the
class. A function is added to the code marked with the Overrides keyword.
Close the Code Preview UML Class Properties windows.
13. Open the UML Class Properties window for the BaseClass. Select
Operations in the Categories list box located on the left side of the UML
Class Properties window. Create a new operation and launch the properties
for the operation. Select Method in the Categories list box. Uncheck the Has
method check box to indicate the method is abstract. Click on the Code
Generation Options and launch the Code Preview window. Notice that the
operation is marked with the keyword MustOveride. Close the Code Preview
window and the UML Class Properties window.
14. Using the process outlined in Step 12, override the abstract
operation you just created in the DerivedClass. Figure 5 shows the completed
diagram.
Review
As you develop complex class structures and interactions in your class
libraries, the importance of accurately modeling and documenting the class
library structure becomes increasingly crucial. A CASE tool such as Visio
makes this complex task more manageable. This article demonstrated the
modeling of class hierarchies using UML and Visio. As you work with Visio to
create your class models, take the time to explore some of the features that
this article did not cover. In particular, you may want to investigate
modeling shared classes, interfaces, and utility classes, all of which are
common to object-oriented applications.
This concludes my series of articles on the modeling of the static
(organizational) structure of an object-oriented application. Along with
modeling the static structure of an application, it is equally important to
model the dynamic (behavioral) aspects of your object-oriented applications.
UML includes a robust set of notations and models for modeling the
behavioral interactions between classes. These include the sequence diagram,
collaboration diagram, and activity diagram. Look for a future series of
articles that will introduce you to the issues involved in modeling the
dynamic interactions that take place between the classes of an
object-oriented application.
About The Author
Dan is a Microsoft Certified Trainer, Microsoft Certified Solution Developer, Microsoft Certified Database Administrator, and a Microsoft Most Valuable Professional. He specializes in developing applications and training others in how to develop applications using Microsoft technologies. Dan is the author of An Introduction to Programming with Visual Basic .NET (Apress).
drc_books@yahoo.com
All Rights Reserved
Copyright © 2004 SYS-CON Media, Inc.
E-mail:
info@sys-con.com