In the UML Class Diagram Part 1 article of this series, you saw what class diagrams were, and how to create class diagrams. In today’s article, you will see a practical example building on our Courseware Management system case study.
Case study—Courseware Management System
The UML class diagram of our Courseware Management System case study can be built after a careful analysis of the requirements. In the previous article, we identified the primary actors and use cases in the use case model of the case study. Because we did much of the groundwork of our analysis while building the use case model, we will use those analysis steps as the basis for identifying the classes and interfaces of this system.
Let us recap the analysis that was performed when the use case model was designed. The following terms and entities specific to the system were identified from the problem statement:
- Courses and Topics that make up a course
- Tutors who teach courses
- Course administrators who mange the assignment of the courses to tutors
- Calendar or Course Schedule is generated as a result of the
- Students who refer to the Course schedule or Calendar to decide which courses for which they wish to sign up
The potential actors of the system were:
- Course administrators
And the use cases of the system were:
- View courses
- Manage topics for a course
- Manage course information
- View course calendar
- View tutors
- Manage tutor information
- Assign courses to tutors
Identifying classes of the Courseware Management System
As you did in use case modeling, you will identify the classes and interfaces using an incremental approach.
- Identify the “active” entities in the system
The basic rule that we learned until now for identifying classes and interfaces is that classes and interfaces reflect important entities of the business domain of the system being modeled. We will apply this rule to determine classes and interfaces of the case study system. At first glance, the actors identified in the use case appear to be prime candidates for being listed as potential classes. Even though we had excluded Students and Tutors from our final list of actors, we will still include them in our list as potential classes. So, our first list of classes in the system appears to be:
- Course administrators
- Identify business domain (“passive”) entities in the system
But these are the “active” entities of the system. We had also identified “passive” elements in the system as well in the analysis for our use case model. These entities reflect the business domain and hence are potential classes for our system.
- Topics that make up a course
- Course calendar generated
Entities that reflect the business terms are also called business domain classes or just “domain classes.” Some of the business domain classes hold transient data and some hold persistent data for the application. Normally, such business domain classes map to either one or many database tables.
For example, in our case study, the Course class can be modeled as a database table cms_course. The data in this table for a particular course will be represented by an instance of the Course class and made available to the rest of the application.
Our two-step process has definitely yielded promising results! We have covered all the relevant items in our analysis. So, let us list the list of classes and interfaces that we have identified in the Courseware Management System.
- Categorize and map the use cases and any relevant business functionality to either the passive or active entities. These will become the business methods of the classes in the system.
Classes encapsulate functionality. The classes that we have identified for the Courseware Management System also provide business functionality related to the application. The functionality encapsulated by these classes is distinct in nature and differs from each class. Recall from our use case model, that, along with actors, we had identified a set of use cases that the actors interacted with. Let us try to associate them with our classes. Because our primary actor is the course administrator and the use cases were related to this actor, we can directly map the use cases to the CourseAdministrator class as methods.
In addition to this, we also can determine some implicit functionality of classes that reflect business entities. For example, what functionality should the Course class provide? Intuitively, we would define the Course class to provide functionality to view all courses in the system, ability to create new courses or modify information of existing courses, view the details of a particular course, or even remove a course from the system. We expect the Course class to provide such business functionality because the Course class reflects a business entity in the system. Hence, these become the methods exposed by the Course class. So, we can now refine the class diagram and add methods to each of these classes.
To cut a long story short, each of the classes that reflect business entities will provide similar implicit business functionality. Let us list all such “implicit” functionality for each of these classes.
Revisit the class diagram and revise it by identifying shared features and/or common functionality between classes or interfaces. These will translate into reusable pieces of code for your system. To some extent, we can say that CourseAdministrator, Tutor, and Student are essentially users of the system. Hence, we can define a shared parent class named User and define basic functionality like for example, authentication, in the User class that can be inherited by the CourseAdministrator, Tutor, and Student classes. It is left to the design expertise to identify reusable classes/functionality.
This completes our analysis of the problem statement to define the classes for the Courseware Management System.
Identifying relationships between the classes of the Courseware Management System
The next step after defining the classes of the Courseware Management System is to define the relationships and dependencies between these classes and interfaces. To define the relationships between the classes, we need to analyze the interconnections between the classes—whether implicit or explicit. Relationship analysis can be broken up into three steps:
- Identify relationships between “active” entities
Active entities normally share generalization relationships (“is-a”). Essentially, the common attributes and functionality between classes are defined in a common parent class. All the related child classes inherit functionality from the parent class. Apart from generalization, a few active entities can also be interconnected by a realization relationship. Recall that elements in a realization relationship implement declared functionality as a “contract.” For example, a set of classes may implement functionality declared as methods in an interface, and this can be modeled as a realization relationship between the interface and the classes implementing the interface.
In our case study, we do not find an example of inheritance relationship between the active entities such as Student, Tutor, and CourseAdministrator or any realization relationships.
- Identify relationships between “passive” business entities
Passive business entities frequently share plain association or aggregation relationships (“has-a”). This is especially true because these business entities are non-transactional in nature and reflect data more than behavior. It is by far quite intuitive to identify aggregation as well as its variations—composition relationships for passive business entities.
Some of the classes in our case study do exhibit aggregation relationships. Because a set of topics makes up a course, we can define an aggregation relationship between the Course and Topic classes. Moreover, we can define this as a directed aggregation, meaning that you can check for the topics of a course but not vice versa. Similarly, we can define a plain association relationship between the Course and Tutor classes and Course and Student classes.
Relationships between active and passive entities can easily be represented using directed association. The directed association, a variation of the “vanilla” association relationship, provides easy identification of which is the container class and which is the contained class. The CourseAdministrator class can be modeled to have a directed association with the Course class. This association can be named as “manages” because the course administrator manages courses as a business activity. In addition to this, because the course administrator also manages the tutor information and topic information, we can model a directed relationship named as “manages” between the CourseAdministrator and the Course and Topic classes, respectively. We can enhance the readability of the association between CourseAdministrator and the Course, Tutor, and Topic classes by defining the multiplicity for the association—one to many, one to one, many to many, and so forth.
Figure 4.2.1 shows the class diagram for the Courseware Management System
We have completed identifying the classes for the Courseware Management System and established the relationships among the classes. Take a look at the class diagram in Figure 4.2.1. The class diagram of the Courseware Management System includes all the classes and their relationships that we identified during our analysis of the problem statement.
|Model View Controller Design|
The class diagram that we designed for the Courseware Management System defined the basic classes necessary for representing the basic structure of the system. But this is by no means a complete design if the architecture of your system is to be based on the Model View Controller (MVC) architecture. Because an MVC model defines clear separation of classes among the three layers—business, presentation, and flow control—you need to define additional classes and revise your design to include them. In case your UML tool does not support explicit partitioning of classes, you can mark classes in each of the layers using stereotypes such as <<entity>>, <<boundary>>, <<control>>, and so forth.
For example, in our case study application, we can revise the class diagram to define a new CMSController class that manages the flow of the application. The model layer primarily consists of classes relevant to the business domain. Next, the classes that we had defined can be categorized as transactional and persistent classes. The CourseAdministrator class performs most of the activities in the system. Hence, this class can be designated as a transaction class of the model layer. Similarly, the Course, Topic, Tutor, CourseCalendar, and Student classes represent persistent business data. Hence, these can be categorized as persistent classes of the model layer. Finally, you can define a set of classes that represent the presentation layer; in other words, the user interface of the system.
Forward Engineering from Class Diagrams
Forward engineering is the process of generating source code (in a specific language) from a class diagram model. The extent to which a UML class diagram can be used to generate source code depends upon the limitations of the source code language. Because UML is pictorial, and can depict a lot of details, these details could be lost in the code. Hence, before creating a complete class model, it is a good idea to be aware of the language that is going to be used, to limit the class model accordingly. Typically, the association relationships between classes are generated as member variables between the related classes in the source code. Generalization relationships are generated as inheritance relationships in the source code.
Figure 4.2.2 shows forward engineering a class diagram
The above screenshot shows the source code file generated for the CourseAdministrator Java source code file as a result of forward engineering the class diagram of the Courseware Management System case study. You need to check how forward engineering works in the tool that you use.
Reverse Engineering of Class Diagrams
Obtaining a class model from existing source code is called reverse engineering. This is generally done when it is required to understand the architecture of an existing system, either for re-engineering, or for maintenance. Reverse engineering is of great use especially when trying to figure out the static structure and organization of a complex system. Typically, classes defined as member variables in the source code are modeled as association relationships between the classes. Inheritance relationships in the source code are generated as generalization relationships between the classes.
Figure 4.2.3 shows reverse engineering a sample source code file
The above screenshot shows a class diagram generated as a result of reverse engineering a sample source code file. You need to check how reverse engineering works in the tool that you use.
In the last article, we saw how class diagrams are the basic building blocks that define the design of a system. We learned about the elements of a class diagram—classes, interfaces, and packages—and the different types of relationships among these elements, such as association, aggregation, composition, generalization, and realization.
Today, we defined a few steps to identify classes and interfaces of a system from a problem statement for designing the class diagram for the Courseware Management System case study.
In the next part in this series, we will study the Object diagram.
About the Authors
Mandar S. Chitnis, Lakshmi Ananthamurthy, and Pravin S. Tiwari are the co-founders of Novusware, Inc.. They have co-authored the book Teach Yourself BEA WebLogic Server 7.0 in 21 Days (SAMS Publishing October, 2002) based on the recently launched WebLogic Server 7.0 by BEA Systems inc.
For any questions or queries regarding the article’s contents, please contact [email protected].