Mastering UML Include Relationships: Reusing Logic in Library Systems

PlantUML Use Case diagram for Student borrowing books and checking fines.

In the realm of software engineering and system architecture, efficiency is paramount. When modeling complex systems, developers often encounter scenarios where specific behaviors need to be executed across multiple different processes. Rather than duplicating logic, UML (Unified Modeling Language) offers a powerful mechanism to maintain modularity and clarity: the Include Relationship.

This tutorial explores how to effectively utilize the <<Include>> relationship, specifically within the context of a library management system. We will break down the diagram below, analyze the architectural decisions behind it, and discuss how to apply these concepts in your own modeling tools like Visual Paradigm.

The Anatomy of the Diagram

Let’s examine the structure of the use case diagram provided. The diagram illustrates a “Borrow Books” scenario involving a Student actor. To ensure the system functions correctly, the base process triggers specific sub-processes that are essential but distinct.

  • The Actor (Student): Represented by the stick figure, this is the user initiating the process of borrowing a book.
  • The Base Use Case (Borrow Books): This is the primary goal of the interaction. It represents the high-level task the user wants to accomplish.
  • Included Use Cases: The diagram features two distinct behaviors: Check Fine and Check Reserved Book. These are linked to the base use case via dashed arrows labeled <<Include>>.

Why Use the Include Relationship?

The core purpose of the include relationship is reusability. Imagine a scenario where Check Fine is a necessary step not just for borrowing books, but also for renewing them or returning them. By defining this logic once as a separate use case, the system architecture remains clean and modular.

When you draw a dashed arrow with the stereotype <<Include>> pointing from the base use case to the included use case, you are establishing a strict dependency. It implies that the base use case cannot be completed without the included functionality.

Step-by-Step Logic Breakdown

To understand the flow of control in the diagram above, consider the execution path:

  1. The Student initiates the Borrow Books process.
  2. The system pauses the main flow and invokes the Check Fine logic. If the student has outstanding fines, the system might block the transaction or require payment. This is a mandatory check.
  3. Simultaneously (or sequentially), the system invokes the Check Reserved Book logic. This ensures that the book being borrowed is not already held by a waiting student. If it is reserved, the base use case might be altered or terminated.
  4. Once these included behaviors are successfully validated, the base use case proceeds to finalize the transaction.

Designing for Modularity

In a real-world application, the Check Fine and Check Reserved Book use cases likely contain complex logic involving database queries, user authentication, and business rules. By extracting these into separate use cases, you achieve several architectural benefits:

  • Single Source of Truth: If the logic for checking fines changes (e.g., the penalty calculation changes), you only update the Check Fine use case, not the base logic of every single interaction that requires it.
  • Clarity: The Borrow Books use case becomes a high-level summary of the process rather than a massive block of text detailing every validation step.
  • Scalability: As the system grows, you can add new triggers to these included use cases without cluttering the main workflow diagrams.

Visualizing the Dependency

When working in modeling tools like Visual Paradigm, you represent this dependency visually. The arrow always points from the base use case to the included use case. This directionality is crucial; it signifies that the base use case is “including” the functionality of the target use case.

Here is how the structural relationship is defined in UML notation:


@startuml
actor Student
usecase "Borrow Books" as Borrow
usecase "Check Fine" as Fine
usecase "Check Reserved Book" as Reserved

Student - Borrow
Borrow ..> Fine : <>
Borrow ..> Reserved : <>
@enduml

Conclusion

The <<Include>> relationship is a vital tool for creating maintainable and readable system models. By separating common behaviors like validation checks or specific data retrievals from the main use case, you create a flexible architecture that can adapt to future changes with minimal friction. In the library example, this ensures that the borrowing process is both robust and logically sound.