Naming Conventions, Visibility, and Access Levels

Estimated reading: 8 minutes 7 views

Many developers start drafting UML class diagrams by labeling classes and methods without pausing to consider how those names will affect future maintainability. I’ve seen teams ship systems where a simple misstep in naming—like using “getInfo()” for a method that modifies state—led to months of confusion. The real issue isn’t the tool or syntax; it’s the lack of a consistent naming strategy that reflects both responsibility and intent. That’s where UML naming conventions come in—not as rigid rules, but as shared language to support collaboration and clarity.

When you move from CRC cards to formal UML, your goal isn’t just to transpose handwritten notes into boxes and lines. You’re translating responsibility-driven design into a structured API. This chapter guides you through naming conventions, visibility rules, and encapsulation strategies—tools that ensure your class diagram doesn’t just look right, but behaves correctly in practice. You’ll learn how to make every name meaningful, every access level intentional, and every boundary well-defined.

Why Naming Conventions Matter in UML

Names are the first point of contact with your design. A poorly chosen class name like “DataHandler” or “Manager” invites ambiguity. A good name, like “OrderValidator” or “CreditCardProcessor,” conveys intent and scope. UML naming conventions are not arbitrary; they’re rooted in the principle that a class’s name should answer: “What role does this play in the system?”

Consider a team modeling a banking system. One developer names a class “Bank.” It sounds simple. But when the model grows, you’re left wondering: Is this the entire bank? A banking service? A customer record? The ambiguity creates friction in code reviews and testing.

UML best practices recommend naming classes with nouns or noun phrases that reflect a specific responsibility. Use singular terms unless the class represents a collection. Avoid verbs in class names—those belong in method names.

  • Use descriptive, singular class names. “Customer” instead of “CustomersManager”
  • Apply camelCase in lower case for package names. “banking.transaction” instead of “Banking.Transaction”
  • Use full, meaningful names. “PaymentProcessor” over “PayProc” or “P”

These aren’t preferences—they’re decisions that reduce cognitive load across teams. A well-named class doesn’t need documentation to be understood. Every line of code written against it becomes more predictable.

Visibility and Access Levels in UML

Visibility is where abstraction and encapsulation begin. UML defines four visibility levels, each with a clear purpose in controlling access:

Symbol Name Scope Use Case
+ Public Accessible from everywhere APIs, service methods
Private Only visible within the class Internal state, temporary logic
# Protected Class and subclasses Base class behavior, inheritance
~ Package Same package only Shared internal logic

When translating CRC responsibilities to UML, ask: “Does this attribute or method need to be accessible beyond this scope?” If not, don’t expose it. Overexposure leads to tight coupling and fragile code.

For example, a CRC card might list “Track transaction status” as a responsibility. In UML, this becomes a method like updateStatus(). But what visibility should it have? If it’s only used by the class itself to manage internal logic, mark it as private. If it’s accessed by subclasses, use protected. If it’s part of a public interface, make it public.

My rule: default to private unless there’s a clear reason to expose. This aligns with the principle of encapsulation UML—data and behavior that don’t need external access should stay inside the class.

Practical Guidance for Visibility

Here’s how to apply visibility in real design:

  1. Start with private. All instance variables and helper methods begin private.
  2. Expose only what’s needed. If a method is only called by another method in the same class, keep it private.
  3. Use protected for inheritance. Only expose for extension, not for arbitrary access.
  4. Use package visibility for shared components. When multiple classes in the same package use a utility, make it package-private.
  5. Public is for interaction. Only public methods are part of the public API.

This approach ensures your class diagram isn’t just a visual layout—it’s a boundary definition that enforces design discipline.

Translating CRC Responsibilities into UML Attributes

One of the most frequent translation errors I see: treating every CRC responsibility as a method, even when it’s actually a data state. A CRC card might say “Store customer details.” That’s not a method—it’s an attribute.

When you see a responsibility like “Hold balance amount” or “Track expiration date,” ask: Is this state? Then, map it to an attribute. For example:

class Account {
  - double balance
  - LocalDate expirationDate
  + void deposit(double amount)
  + boolean isValid()
}

Here, balance and expirationDate are private attributes—because they’re internal state. The methods deposit and isValid are public because they define observable behavior.

This distinction is critical. You’re now aligning CRC to UML attributes correctly: state goes in, behavior goes out. When you reverse this, you risk exposing internal data or hiding critical behavior.

Attribute Naming Best Practices

Attributes should be precise, unambiguous, and consistent. Use descriptive names that reflect both purpose and type.

  • customerName – clear and specific
  • amount – too vague; better: transactionAmount
  • isPaid – good for boolean; avoids paidStatus or status

Never use abbreviations unless they’re standard (e.g., id for identifier, addr is less clear). Clarity trumps brevity.

Encapsulation UML: More Than Just Visibility

Encapsulation in UML isn’t just about visibility—it’s about control. A class that exposes its data via public fields is not encapsulated, no matter how many private methods it has.

True encapsulation means: data is internal, access is controlled, and changes are isolated. Use getters and setters not as boilerplate, but as gates. For example:

class BankAccount {
  - double balance

  + getBalance(): double
  + deposit(amount: double): void
  + withdraw(amount: double): boolean
}

Now, if you later decide to add interest calculation, you can do it in getBalance() without breaking existing code. If balance were public, every access point would need to be updated.

Encapsulation prevents unintended side effects. It turns a data holder into a responsible entity. This is what encapsulation UML means in practice: design with intent, not convenience.

Final Checklist: From CRC to UML

Before finalizing your class diagram, run through this checklist:

  • Are all class names descriptive and singular?
  • Are all attributes private unless shared across packages?
  • Are methods public only when they form part of the public interface?
  • Are there any public fields? If yes, consider replacing with getters/setters.
  • Have you reviewed visibility in the context of inheritance and package boundaries?
  • Does every name reflect a clear responsibility or state?

These aren’t just good practices—they’re the foundation of a design that can evolve, test, and scale.

Frequently Asked Questions

What’s the best way to name a class derived from CRC?

Start with the CRC responsibility: “Manage user accounts” becomes “UserAccountManager.” But ask: is this a service or a domain object? If it’s a central entity, use “UserAccount.” If it’s a utility, “AccountManager” may be clearer. Prioritize clarity over brevity.

Can I use protected access for all methods in a class?

No. Protected access is for inheritance, not for all internal logic. Use private for internal helpers. Reserve protected for methods that subclasses must override or extend. Overusing protected breaks encapsulation and increases coupling.

How do I handle boolean attributes in UML?

Use a clear, positive name like isActive, isVerified, or hasPermission. Avoid active or verified alone, as they’re ambiguous. Always prefix with “is” or “has” for boolean attributes.

Why should I avoid public fields in UML?

Public fields break encapsulation. They allow direct modification, making it impossible to add validation, logging, or transformation later. Treat every public field as a design flaw—replace it with a getter/setter pair or a method that controls access.

What if a CRC responsibility doesn’t map to a method or attribute?

Revisit your interpretation. Every CRC responsibility should map to a method (behavior) or an attribute (state). If it doesn’t, you may have misunderstood the responsibility. Ask: “What does this entity own? What does it do?” If it doesn’t answer one of those, re-express the responsibility.

How do I ensure naming best practices across a team?

Establish a shared naming convention early. Use your CRC sessions to agree on terms. Document them in a style guide. Use tools like Visual Paradigm to enforce consistency. Regular design reviews should include a naming audit.

Design isn’t about writing code. It’s about creating a shared language. When you get naming right, visibility right, and encapsulation right, you’re not just building a diagram—you’re building a system that speaks clearly to its future maintainers.

Share this Doc

Naming Conventions, Visibility, and Access Levels

Or copy link

CONTENTS
Scroll to Top