[CSUSB] >> [CompSci] >> [Dick Botting] >> [CS202 Course Materials] >> uml1b
[Index] || [Contents] Fri Nov 8 14:10:14 PST 2002

Contents


    UML Object Models

    This is part of my notes on the Unified Modeling Language(UML) that covers more features of C++ such as templates, pointers, linked lists, etc. See [ uml1.html ] for a simple introduction and [ uml.html ] for an over-view and introduction to the UML. To learn how to use Rational Rose on the csci.csusb.edu domain see [ uml3.html ] for detailed instructions. Some advanced features are covered in [ uml4.html ] that includes constraints, extensions, class utilities, hints on designing classes and some common patterns.

    Classes and Objects

    In the UML a class of similar objects is drawn as a rectangular box. It can just contain the name of the class. It can also have two parts: the top part for the name and the second part for the attributes of the objects. It can have three parts: the name, the attributes, and the operations. Classes are often linked together with associations as well. See [ Classes in uml1 ] for more details.

    The UML also allows you to show a collection of objects. Here is an example of a class (Person) and three typical objects of type Person.

     Person and People

    Notice: the parts of the box are not: Name, Private, Public! There can be public and private attributes -- but they are usually private. There can be public and private functions(operations) -- but the are often public. Private attributes and functions have a minus sign in front of them. Public parts have a plus sign.

    UML diagrams show a collection of named boxes - indicating classes or types of object. The boxes have lines connecting them called links. Each link is called an association and should model some relationship or connection between the classes. Associations also play roles in classes that are often given special names.

    Templates

    You have met the idea of templates in C++. The library if full of templates like vector, lists, stack, and queue. A template has a parameter that is given a particular value when the template is used:
    TemplateInstance
    vectorvector<string>
    listlist<string>
    UML calls a template class a "parameterized class" and has a special notation for the class, and its instances. Here is a sketch of the STL list template, the STL list iterator, and a couple of instances list<string> and iterator<string>:

    The C++ list template

    Special Relationships Between Classes

    We can use diagrams to talk about existing code and we can also use them to work out new code. There are some special relationships that hold between classes of objects in a piece of code: Dependency, Composition, Aggregation [ Linked Data Structures ] , Generalisation, Inheritance, Overriding etc..

    Dependency

    It is often useful to know that one class make use of another class in some way or other. This is shown as a dotted arrow from the client class to the class that provides the service.

    A--->B

    For more information see [ Dependency in uml1 ] in the previous notes on UML.

    Composition

    UML provides several notations that can express the physical construction of a class. The filled in diamond is often used when a class contains other objects within them as parts or components. Here are two ways of showing the same structure: A class named Period has two components: time (an array of 2 times) and days (a vector of Days).

    Composition of Period

    Use either a diamond link or an attribute for each data member! Do not show both for one member. Each diamond indicates a specific member of the class -- it is wise to add the role name.

    We use the dark diamond to indicate that the class possesses the components in the sense of controlling whether they exist of not. The filled in diamond indicates that the deletion of an object may delete its components as well. The diamond indicates that the class is responsible for protecting and preserving an object of the other type. You can clarify the details by adding a stereotype like "<<creates>>", "<<uses>>", "<<deletes>>", etc. .

    Aggregation

    We can also show that a class has some parts that have an independent existence. In C++ this happens when we use pointers to refer to objects instead of storing the actual objects inside another object. An object in C++ can store A page on the world Wide Web can use a hypertext reference to point to another resource -- deleting the page does not effect the other page. In a data base, a record can store the key of another record and so connect the records. For a real world example consider a restaurant: People may be clients of the Restaurant, but they are not part of it!

    These loose connections are shown by an open or empty diamond, something like this:

     		<>--

    Here is an example showing that a Restaurant will have a number of clients who are People and the the clients exist whether or not they are clients of the Restaurant:

    Association: Restaurant has Clients

    In the above there are two diagrams. They differ in a single asterisk and this makes the difference between a realistic model of people and restaurants and an unrealistic one.

    Exercise: Which is more realistic?

    The other end of the Aggregation link is used to indicate whether the association can be navigated in both directions or only one:

     		<>----->	Can follow link in one direction
     		<>------	Can follow link in either direction

    Linked Data Structures

    In the UML you should never show a C++ pointer as an attribute with an asterisk on it. In the UML and asterisk means "any number" not "is a pointer". You can use an attribute whose type is the name on the type pointed at (with no asterisk). For example to show a C++
     		Person * mother;
    you can just use, in the UML
     		mother : Person

    Sometimes we want to make the precise physical connection clear. To do this use a one-way aggregation:

     		<>----->
    and add a (0..1) multiplicity to the arrow end. The multiplicity will remind you that a pointer may have a NULL value and so point at no objects at all. So here is the UML diagram of one implementation of the Person class:

    person with pointers

    and here is part of the C++ code:

     		class Person {
     		private:
     			Person * mother;
     			Person * father;
     			vector <Person *> children;
     		...
     		};
    Notice that we don't need to say "vector" in the UML.

    The UML is designed so that it is possible to use Aggregation and Composition to model the linked data structures of computer science. For example the following C++ class and diagram all indicate the same classes.

     		class IntLink {
     		  public:
     			int data;
     			IntLink *next;
     		};//end IntLink
     		class IntList {
     		  public:
     			IntLink *first;
     		};//end IntList
    UML diagram of IntLink Linked Objects Faked addresses

    Notice that IntLink * does not appear in the UML!

    Many-to-Many and Two-way Links

    Notice that if the arrow head is missing:
              <>------        Can follow link in either direction
    then the C++ code must have two pointers stored. One is needed at each end of the aggregation.

    When the aggregation has multiplicities other than "0..1" then this implies a container of pointers is needed, not just a single pointer. So, for example:

    Enrollment

    In C++ we may need to declare an data item:

     		vector < Section * > schedule;
    or
     		list < Section * > schedule;
    If the aggregation is two way from Student to Section and back again (no arrow head) then we also have in the Section:
     		vector < Student * > roster;
    or
     		list < Student * > roster;

    Finally when you have many-to-many two-way aggregations you may want to introduce a class to connect the two parts together and use links to explicitly create lists of the links:

     	class Student{
     		Enrolment * first_class;
     		Enrolment * last_class;
     		...
     	};
     	class Schedule{
     		Enrolment * first_on_roster;
     		Enrolment * last_on_roster;
     		...
     	};
     	class Enrolment{
     		Student * student;
     		Section * section;
     		Enrolment * next_class;
     		Enrolment * prev_class;
     		Enrolment * next_on_roster;
     		Enrolment * prev_on_roster;
     		...
     	};

    Notice how one simple relations can be coded in many ways. Computer Science is about being able to choose a suitable implementation from the dozens that should work.

    Generalization

    In C++ we can construct a new class that is derived from another class:
     		class Derived: public Base { added_features };
    This means that the new Derived class extends the property of the old Base class. Each object of Derived can do anything that an object of Base can. Each Derived object holds all the data that a Base object does. Derived classes can redefine and extended the data and operations of the Base class.

    In UML this relationship is called generalization. This is a relationship that is naturally expressed with a sentence like this: "Every ____ is also a _____". Here is the simple UML diagram that states that Every Student is also Person:

    Diagram 2:Student specialized from Person

    As drawn the diagram does not allow a Person to become a Student. In a program this would mean that the class Student would extend or inherit all the properties from Person and C++ we can implement this by writing:

    	class Student : public Person { ... }

    This means that

    Generalization is commonest in the more formal domains of geometry (see Abstraction below) mathematics, and legislation.

    We say the new class is a subtype and the original class is a supertype. It should only be used when every object in the new class is automatically also an object of the class it is derived from. A subtype is a class that shares all the properties of its parent, supertype, or the class it is derived from.

    Generalization vs Composition

    Some people get a little confused at first between composition (has parts) and generalization (is a kind of). The following diagram tries to make the difference obvious: A Face is a general kind of smiling face. A Face has eyes and a mouth:

    Faces in the UML

    Notice that the instance of a smiling face has eyes and a mouth. It inherits them from Face.

    Inheritance

    Logically generalization means that anything that can be done to or by a Person can also be done to or by a Student. We say that "Student inherits from Person". In the UML this is indicated by default -- when ever the student doesn't list a public feature in a child class it can inherit the parent's version.

    Overriding

    However a Student may sometimes react with different behavior than the more general Person does. This is called over-riding.

    For example, Student objects where shown above as special kinds of Person. This means that each student automatically has all the properties of a Person. It "inherits" all the attributes and all the operations from its parent type. It is also possible to show that Student has something different with the same name as Person. To show, for example, that there is an operation to display information about a Person we would add display() to the operations in Person. Instantly, Students also gain (invisibly) the ability to be displayed. But suppose we wanted to make students to behave differently - to display different information to the Person. Then we would put display() in with the operations of Student!

    It is normal in object-oriented programming to find that same operation in many different classes each time with a different behavior. Thus objects know which version of the functions are to be invoked. This technique avoids much of the complex coding needed in structured programming.

    Attributes can also appear in both Parent and Child. The child's attribute effectively make the Parent's version unavailable... but both are still stored in the object.

    . . . . . . . . . ( end of section Generalization) <<Contents | Index>>

    . . . . . . . . . ( end of section Special Relationships Between Classes) <<Contents | Index>>

    Properties of Members of Classes

    UML provides ways for documenting most of the properties of items that you list in a C++ class decoration: See Privacy, Friendship, Constructors, and [ Classwide and Static Parts ] below. In addition to the simple notations mentioned below tools will often use neat graphics, colors, or fonts instead.

    Privacy

    Public, private, and protected members of classes are indicated by putting a plus-sign(+), minus sign(-), and hash mark(#) respectively in front of the attribute, operation, or role. In Rational Rose these appear as nothing, a padlock, and a key respectively.

    Const

    The C++ const member function can be indicated by the stereotype <<query>> if you want in the UML.

    Constructors

    Most people don't worry about showing constructors in the UML. CASE tools allow you to specify default values for newly constructed objects in a class.

    If it would help a project to document some special constructors do two things. First you can put

     		<<constructor>>
    above the operation.

    Second a constructor has to be a class-wide or static member function because a constructor creates a new object for the class so it can not operate on an existing object. We don't write p.Person() for example. This means that the operation is a class-wide operation and should be underlined or prefixed by a dollar sign.

    Classwide or Static Parts

    Constructors belong to a class rather than a particular object. We therefore say they are class-wide or static operation.

    Other operations and attributes belong to the whole class rather than a particular object in that class. For example the number of students in a college is not an attribute of a particular student but it is an attribute of the class or set of students. Similarly, the operation of working out the GPA of a whole college is different to working out the GPA of a single student.

    Similarly you sometimes need a constant that is shared across a class -- for example a double length value for pi in a mathematical class. You may also want to share a C++ variable across all objects in a class. For example in a class modeling a line of people needs pointers to the first and last people in the line. These two pointers are not present in every person in the line. They are a property of the line as a whole.

    Similarly some operations belong to a class rather than to an individual... for example finding the person with the highest score in a class is not a function of one student but of the whole class. Another example would be reporting how many instances there are of a particular class of objects.

    In C++ variables, constants, and operations that belong to the class and are shared by all objects of the class are declared to be "static".

    In UML you show this by underlining the attribute or operation. It may appear on some displays and printouts in italic form. Some people may also use a dollar sign for this purpose.

    Friendship

    We sometimes need an operation that has full access to a classes private information and yet must not be applied to a single object. In C++, for example, we have "friend functions" and "friend operations". These are indicated by placing the stereotype "<<friend>>" in front of the operation in the UML class diagram.

    We can also document this with a dependency link from the friend to the class extending friendship.

    . . . . . . . . . ( end of section Properties of Members of Classes) <<Contents | Index>>

    Glossary

    Note. In this glossary a definition is written like this
     		defined_term::=what_the_term_means.
    When there are several alternative meanings they are separated by a vertical bar symbol: "|". This is an informal extension of the notation Jim Backus and Pete Naur developed in 1960. [ BNF in glossary ] [ BNF in comp.text.Meta ] [ algol60.syntax.html ]

  1. ADT::="Abstract Data Type". A collection of operations that operate objects with an unknown or hidden structure. An ADT tells you what you can do to the data objects but not how they are stored or how their code is implemented.

  2. UML::=Unified Modeling Language. [ uml.html ]

  3. abstract::stereotype=indicates that a class defines an abstraction so that no objects of this type exist except as objects of the specific subtypes of this type.
  4. abstraction::=the process or result of leaving out details.
  5. application_domain::=a collection of more or less similar solutions.
  6. association::=a connection between objects. Indicated by drawing a line joining the classes.
  7. attributes::=values that an object or class is responsible for maintaining.

  8. constructor::stereotype=indicates that an operation creates a new object of its class.

  9. destructor::stereotype=indicates that an operator deletes an object of its class.

  10. domain::= problem_domain | application_domain.

  11. generalization::=the process or the result of making something more general.

  12. interface::stereotype=indicates that a type is an abstract data type consisting solely of operation prototypes. An interface can implemented by one or more other types and can be used by one or more types.

  13. problem_domain::=a collection of more or less similar problems selected for practical or theoretical reasons.

  14. operations::=things that an object or a class knows how to do.

  15. stereotype::UML=a special note looking like this: <<example>> that adds to the meaning of a UML diagram.

  16. subtype::=One class is a subtype of another class if all the operations of the second class of object also apply to objects of the first type - perhaps in a different way.

    Next

    More on generalization and inheritance: [ uml1c.html ]

    Advanced features and hints: [ uml4.html ]


    (Dynamics): [ uml2.html ]


    (Using Rational Rose): [ uml3.html ]

    . . . . . . . . . ( end of section UML Object Models) <<Contents | Index>>


Formulae and Definitions in Alphabetical Order