PlantUML Class Diagram Syntax Guide

What is a Class Diagram?

A UML Class Diagram is the foundational structural blueprint of object-oriented modeling. It maps out a software system by visualizing its classes, their internal attributes (data fields), their methods (functions), and the structural relationships between them. While code bases can become sprawling and hard to parse, a clean class diagram provides engineers with an immediate visual reference of how code objects interact, inherit behaviors, and manage data boundaries.

Using VPasCode, you can design detailed class layouts entirely in plain text, leaving the layout engineering, box sizing, and line spacing completely to our integrated cloud engines.

Core Syntax Guide: Elements and Constructs

To write high-quality class diagrams, you need to understand three core structural markers: defining the class body, assigning visibility modifiers to members, and mapping object relationships.

1. Declaring Classes and Members

You declare a standard object blueprint using the class keyword. Inside the trailing curly braces, you list your fields and methods on separate lines:

class CustomerAccount {
    String accountId
    String emailAddress
    Boolean isActive()
}

2. Visibility Modifiers (Access Control)

PlantUML maps standard object-oriented encapsulation rules (public, private, protected, and package-private) using simple text prefixes right before the field or method name:

  • + Clear Public access (Accessible by any other class)
  • - Strict Private access (Only accessible within this specific class)
  • # Protected access (Accessible within this class and its subclasses)
  • ~ Package/Internal access (Accessible only within the local code module)

3. Defining Object Relationships

Connecting classes requires specific arrow notations to indicate the structural dependency or composition of your application code:

  • Inheritance / Generalization (Is-A): Uses an open triangle arrow head pointing to the parent class: SubClass --|> ParentClass
  • Implementation / Realization: Uses a dotted line with an open triangle to show an interface execution: ConcreteClass ..|> IInterface
  • Composition (Strict Ownership): Uses a solid diamond to show that the child object cannot exist without the parent container: Parent *-- Child
  • Aggregation (Shared Collection): Uses an open diamond to show a temporary collection relationship: Department o-- Employee

Best Practices for Practical Class Maps

  • Separate Layouts with Abstract Classes: Use the abstract class or interface keywords to visually differentiate your structural boundaries from concrete database models.
  • Label Multiplicities Early: Always add numerical multiplicities (like "1" or "0..*") on both ends of your relationship arrows to make data constraints explicit for developers.
  • Control Vertical Spacing: Class diagrams can grow extremely tall. If your layout stretches too far vertically, replace a double dash (--) with a single dash (-) inside your relationship arrows to force a side-by-side horizontal alignment.

Real-World PlantUML Class Diagram Examples

Example 1: E-Commerce Domain Model (Visibility & Encapsulation)

This blueprint demonstrates standard access modifiers, basic data objects, and basic data multiplicity mappings between core online shopping entities.

@startuml
class User {
    - String userId
    - String hashedSecret
    + Boolean verifyLogin(String input)
}

class Order {
    + String orderId
    + Date timestamp
    - Double calculateTotal()
}

User "1" --> "0..*" Order : "places and owns"
@enduml

Syntax Breakdown: The - prefix keeps sensitive fields like credentials strictly private inside the User class block, while public access functions use the + marker. The connection string explicitly highlights that one user can look up zero or many orders seamlessly.

Example 2: Advanced Payment Gateway (Inheritance & Interfaces)

This comprehensive software engineering map showcases how to organize interfaces, class inheritance loops, and complex compositions within a unified framework.

@startuml
interface IPaymentProcessor {
    + Boolean authorizeAmount(Double cash)
    + void captureFunds()
}

abstract class BaseGateway {
    # String merchantApiKey
    # String endpointUrl
    + void logTransaction(String payload)
}

class StripeGateway {
    - String stripeToken
    + Boolean authorizeAmount(Double cash)
    + void captureFunds()
}

class PayPalGateway {
    - String paypalEmail
    + Boolean authorizeAmount(Double cash)
    + void captureFunds()
}

class ShoppingCart {
    - List items
    + void checkout(IPaymentProcessor engine)
}

' Structural relationship declarations
BaseGateway ..|> IPaymentProcessor
StripeGateway --|> BaseGateway
PayPalGateway --|> BaseGateway
ShoppingCart *-- IPaymentProcessor
@enduml

Syntax Breakdown: The ..|> notation establishes that the abstract class implements our primary root interface. The solid triangle lines (--|>) route the child gateways cleanly into their base parent class, while the solid diamond (*--) declares that a ShoppingCart fundamentally owns its payment engine processor during a session lifecycle.

Scroll to Top