Mermaid Class Diagrams — Data Model Visualization
In this tutorial, you will learn about Mermaid Class Diagrams. We cover key concepts, practical examples, and best practices to help you master this topic.
Mermaid class diagrams represent the structure of a system by showing classes, their attributes and methods, and the relationships between them including inheritance and composition.
In this lesson, you will learn class diagram syntax, declaring classes with members, relationship types, visibility markers, namespaces, and annotations for comprehensive data model documentation.
What You'll Learn
You will master Mermaid class diagrams: class declarations with attributes and methods, relationship types (inheritance, composition, aggregation, dependency), visibility markers, and namespaces.
Why It Matters
Class diagrams are essential for documenting object-oriented systems, database schemas, and API data models. They help developers understand the structure before reading implementation code.
Real-World Use
DodaZIP's compression module uses class diagrams to document the class hierarchy. New contributors understand the architecture in 10 minutes instead of exploring 50 source files.
classDiagram
class CompressionStrategy {
+compress(data: bytes): bytes
+decompress(data: bytes): bytes
}
class ZipStrategy {
+compress(data: bytes): bytes
+decompress(data: bytes): bytes
-validate_format(data: bytes): bool
}
class SevenZipStrategy {
+compress(data: bytes): bytes
+decompress(data: bytes): bytes
}
CompressionStrategy <|-- ZipStrategy
CompressionStrategy <|-- SevenZipStrategy
def create_class_diagram(classes, relationships):
"""Generate Mermaid class diagram syntax."""
lines = ["classDiagram"]
for cls in classes:
lines.append(f" class {cls['name']} {{")
for attr in cls.get("attributes", []):
lines.append(f" {attr['visibility']}{attr['name']}: {attr['type']}")
for method in cls.get("methods", []):
params = ", ".join(f"{p['name']}: {p['type']}" for p in method['params'])
lines.append(f" {method['visibility']}{method['name']}({params}) {method['return_type']}")
lines.append(" }")
for rel in relationships:
arrow = {"inheritance": "<|--", "composition": "*--", "aggregation": "o--"}.get(rel['type'], "-->")
lines.append(f" {rel['from']} {arrow} {rel['to']}")
return "\n".join(lines)
diagram = create_class_diagram(
[{"name": "Animal", "methods": [{"name": "speak", "params": [], "return_type": "void", "visibility": "+"}]},
{"name": "Dog", "methods": [{"name": "speak", "params": [], "return_type": "void", "visibility": "+"}]}],
[{"from": "Animal", "to": "Dog", "type": "inheritance"}]
)
print(diagram)
def add_namespace_class(diagram_text, namespace, class_name, members):
"""Add a namespaced class to a class diagram."""
block = f" namespace {namespace} {{\n class {class_name} {{\n"
for member in members:
block += f" {member}\n"
block += " }\n }"
return diagram_text + "\n" + block
diag = "classDiagram\n class Base"
new_diag = add_namespace_class(diag, "Models", "User",
["+id: int", "+name: string", "+save() void"])
print(new_diag)
def add_class_annotation(diagram_text, class_name, annotation):
"""Add annotation to a class."""
return diagram_text + f"\n class {class_name} {{\n <<{annotation}>>\n }}"
diag = "classDiagram\n class UserFactory"
print(add_class_annotation(diag, "UserFactory", "interface"))
Teacher Mindset
Think of class diagrams as blueprints for your code. An architect draws a blueprint before constructing a building. A class diagram draws the structure before writing implementation code. It reveals design issues early: missing attributes, wrong relationship types, circular dependencies. The time you spend creating a class diagram is time saved in Refactoring.
Common Mistakes in Class Diagrams
1. Including Every Private Implementation Detail
A class diagram should show the public interface and key relationships. Private helper methods with 20 lines of implementation detail clutter the diagram.
2. Wrong Relationship Arrow Direction
Inheritance arrows point from child to parent. Dependency arrows point from dependent to dependency. Getting arrows wrong misleads readers about the architecture.
3. Missing Visibility Markers
Attributes and methods without visibility markers leave readers guessing. Use + for public, - for private, # for protected, and ~ for package-private.
4. No Relationship Multiplicity
One-to-one, one-to-many, and many-to-many relationships need multiplicity annotations: "1", "0..", "1..". Without them, relationship semantics are unclear.
5. Classes Without Any Attributes or Methods
Empty classes suggest incomplete documentation. If a class has no public members, consider whether it should be in the diagram.
Practice Questions
1. What is the difference between composition and aggregation? Composition (filled diamond) means the child cannot exist without the parent. Aggregation (empty diamond) means the child can exist independently.
2. How do you show inheritance in Mermaid class diagrams?
Use <|-- with the child class on the right: ParentClass <|-- ChildClass. The arrow points toward the parent.
3. What visibility markers are available in Mermaid? Plus (+) for public, minus (-) for private, hash (#) for protected, and tilde (~) for package-private.
4. How do you represent abstract classes or interfaces?
Use the <<interface>> or <<abstract>> annotation inside the class block. These appear as stereotypes above the class name.
5. Challenge: Create a class diagram for a simple e-commerce system with Customer, Order, Product, and Payment classes. Include attributes, methods, inheritance, and composition relationships.
FAQ
Mini Project
Document the data model of a feature from Doda Browser or DodaZIP using a class diagram. Include at least 5 classes, relationships with correct arrow types, visibility markers on all members, and namespace groupings.
What's Next
Mermaid Gantt in the next lesson.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro