Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update naming conventions #9539

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,15 @@ title: Rules to Better Naming Conventions
guid: 5e9a6545-bca8-4178-b807-a11900b03149
uri: rules-to-better-naming-conventions
index:
- follow-naming-conventions
- clear-meaningful-names
- nouns-for-class-names
- verbs-for-method-names
- avoid-generic-names
- avoid-micro-jargon
- consistent-words-for-concepts
- when-to-use-technical-names
- avoid-using-your-name-in-client-code
- use-meaningful-modifiers
- follow-naming-conventions-for-your-boolean-property
- do-you-know-that-webapi-and-tables-name-should-be-consistent
- follow-naming-conventions-for-tests-and-test-projects
Expand Down
46 changes: 46 additions & 0 deletions rules/avoid-generic-names/rule.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
---
seoDescription: Generic names like "manager" are easy and can trick us into thinking they are good for consistency. But they can quickly undermine conveying the meaning of your code.
type: rule
archivedreason:
title: Do you avoid generic names like “manager” or "helper"?
uri: avoid-generic-names
created: 2024-11-05T00:00:00.0000000Z
authors:
- title: Matt Goldman
url: https://ssw.com.au/people/matt-goldman
related:
- clear-meaningful-names
- verbs-for-method-names
- nouns-for-class-names
- avoid-micro-jargon
- consistent-words-for-concepts
- when-to-use-technical-names
- avoid-using-your-name-in-client-code
- use-meaningful-modifiers
- follow-naming-conventions-for-tests-and-test-projects
guid: f0b473e1-c892-4a21-8319-68f56f713c0d
---

Generic names like “manager”, "helper", “processor”, “data”, and “info” are easy to reach for, but they tell us very little about a class or method’s true purpose. These words are catch-alls — they don’t communicate what the code actually does or what entity it represents. Avoiding these vague terms forces us to choose names that reflect a specific role or responsibility.


<!--endintro-->

## Why generic names are problematic
Words like "manager" and "processor" imply something that handles various tasks, which can make it tempting to pile unrelated responsibilities into one class. "Helper" makes this worse as it becomes a catch-all for a collection of disorganized functionality.Names like "data" or "info" are similarly ambiguous, as they could apply to nearly anything, from a database connection to a simple string. Specific names are always preferable, as they make the code easier to understand and prevent code bloat from accumulating unrelated functionality.

:::bad
Imagine you’re writing a class to handle orders in an e-commerce system. You name it `OrderManager`. While this name suggests that it might have something to do with orders, it doesn’t clarify how it interacts with them. Is it creating orders, updating them, processing payments, or all of the above? The generic term “manager” gives us no clear indication.
:::

:::good
A better name could be `OrderProcessor`, but if the class specifically handles only one aspect — say, sending orders for shipment — a more precise name would be `ShippingOrderHandler` or `OrderShipmentService`. This name directly reflects its purpose, making it immediately clear what the class is responsible for.
:::

:::bad
Let’s say you’re building a system to track medical records, and you create a class called `PatientData`. The name could apply to anything — health information, appointment history, test results. There’s no way to tell what role this class actually plays.
:::

:::good
If the class is responsible for managing a patient’s appointment history, a more accurate name could be `PatientAppointmentHistory`. This name immediately tells us the scope and purpose of the class without relying on catch-all terms.
:::
64 changes: 64 additions & 0 deletions rules/avoid-micro-jargon/rule.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
---
seoDescription: Using a shortcut term that's well-understood within your team can seem like a powerful heuristic, but it requires specific insider knowledge that's at risk of being lost.
type: rule
archivedreason:
title: Do you avoid micro-culture jargon and insider terms?
uri: avoid-micro-jargon
created: 2024-11-05T00:00:00.0000000Z
authors:
- title: Matt Goldman
url: https://ssw.com.au/people/matt-goldman
related:
- clear-meaningful-names
- verbs-for-method-names
- nouns-for-class-names
- avoid-generic-names
- consistent-words-for-concepts
- when-to-use-technical-names
- avoid-using-your-name-in-client-code
- use-meaningful-modifiers
- follow-naming-conventions-for-tests-and-test-projects
guid: bf8b49d4-82f7-42fc-9e56-01076e6e5732
---

Code that relies on nicknames, abbreviations, or internal jokes can create unnecessary obstacles for new team members or future collaborators. Terms that only make sense to the “in-group” (like a specific project team or company department) can be hard to interpret, causing frustration and slowing down onboarding. Instead, favor widely understandable names or domain-specific terms that reflect a shared understanding of the business or domain.


<!--endintro-->

:::greybox
**How this differs from ubiquitous language**
Using ubiquitous language is about naming concepts in ways that align with terms used by domain experts and stakeholders. While this might seem like micro-culture jargon at first glance, it’s different for an important reason. Unlike insider terms, ubiquitous language refers to widely recognized ideas within the domain, making code clearer for anyone familiar with the field. Avoid in-grouped terms that don’t convey meaning to people outside the team, even if they seem descriptive to those who are “in the know.”
:::

:::bad
Imagine you’re working on a temperature regulation system and need functions to identify areas where the temperature has exceeded an upper or lower threshold. You write an enum to represent the state of an area that’s too hot or too cold:
```csharp
enum ThresholdBreachState
{
Hoth,
Mustafar
}
```
Now, this is actually pretty awesome, and if I saw this in your code, I’d probably buy you a beer. But realistically, this is too niche a description, and the mental leap required to connect the dots is burdensome.
:::

:::good
A more universally understandable version would be:
```csharp
enum ThresholdBreachState
{
MaxExceeded,
MinExceeded
}
```

:::bad
Let’s say you have two developers on your team who are unusually tall and short, colloquially referred to as Big John and Little Dave. You’re working on code to compress and decompress messages entering and leaving a queue and name the methods `BigJohnify` and `LittleDavify`. Although the prefixes may hint at the methods’ functions, this requires a specific knowledge of the team dynamic and could easily lead to confusion.

For instance, if nicknames are used ironically (think of “Little John” from Robin Hood), it’s possible that `LittleDavify` actually decompresses messages while `BigJohnify` compresses them. Did you spot the word "respectively" at the end of the first sentence? Anyone “in the know” might understand this, but it demands unique insider knowledge and risks being both unprofessional and confusing.
:::

:::good
A far better method name pair would be `CompressMessage` and `DecompressMessage`. They are clear and concise to anyone reading the code, without the need for insider knowledge or the cognitive load of applying it.
:::
40 changes: 40 additions & 0 deletions rules/avoid-using-your-name-in-client-code/rule.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
---
seoDescription: We often use ours or our company name to denote a custom version of something. Unless you're publishing a library, this is never a good idea.
type: rule
archivedreason:
title: (For consultants) Do you avoid using your or your company’s name in client code?
uri: avoid-using-your-name-in-client-code
created: 2024-11-05T00:00:00.0000000Z
authors:
- title: Matt Goldman
url: https://ssw.com.au/people/matt-goldman
related:
- clear-meaningful-names
- verbs-for-method-names
- nouns-for-class-names
- avoid-generic-names
- avoid-micro-jargon
- consistent-words-for-concepts
- when-to-use-technical-names
- use-meaningful-modifiers
- follow-naming-conventions-for-tests-and-test-projects
guid: 7d9eb8d3-4522-40c9-bcbd-b22f48f50edf
---

When building solutions for clients, it’s tempting to include personal or company identifiers in control or component names, like `GoldieEntry` or `SSWButton`. However, naming controls after yourself or your company in client projects can create confusion, dilute the client’s branding, and look unprofessional. For consultants, the goal should be to name components in ways that make sense within the client’s business context.


<!--endintro-->

## Why It Matters
Names that reflect the client’s brand or domain are clearer and more meaningful for the client’s internal teams and stakeholders. They also reduce the risk of naming conflicts and make it easier for future developers to understand the purpose of a component in context.

:::bad
Naming a custom entry field `GoldieEntry` or `SSWEntry` might make sense in a personal or shared library but is out of place in a client project.
:::

:::good
Instead, using something like `NorthwindStepper` is more client-aligned and indicates that this is a customized variation of a standard control.

**Note:** This approach is ok to denote a branded version of something, but often it's better to indicate the customization itself in the name. See our rule [Do you use meaningful modifiers for custom implementations?](/use-meaningful-modifiers).
:::
69 changes: 69 additions & 0 deletions rules/consistent-words-for-concepts/rule.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
---
seoDescription: It's a common belief that consistency matters more than anything else in your code, and this is especially true of the names you use to represent concepts.
type: rule
archivedreason:
title: Are you consistent with the words you use to represent concepts?
uri: consistent-words-for-concepts
created: 2024-11-05T00:00:00.0000000Z
authors:
- title: Matt Goldman
url: https://ssw.com.au/people/matt-goldman
related:
- clear-meaningful-names
- verbs-for-method-names
- nouns-for-class-names
- avoid-generic-names
- avoid-micro-jargon
- when-to-use-technical-names
- avoid-using-your-name-in-client-code
- use-meaningful-modifiers
- follow-naming-conventions-for-tests-and-test-projects
guid: 782822da-92e3-4912-855b-cf1f2a05542b
---

There’s more than one way to skin a cat (apparently—we don’t have any rules on cat-skinning), and equally, there’s often more than one term to represent a concept. While some terms may have nuanced differences, they can often seem interchangeable. But once you’ve picked a term, stick with it and use it everywhere. Inconsistent language is one of the quickest ways to violate the DRY principle and add unnecessary complexity to your codebase.


<!--endintro-->

## Why Consistency Matters
### The DRY Principle
The DRY (Don’t Repeat Yourself) principle states that within a codebase, there should be a single authoritative source of knowledge for each concept. Inconsistent naming makes it harder for developers to find existing code, as they may search for one term and miss relevant code that uses another name.
### Cognitive Load
Using multiple terms to describe the same thing adds cognitive load and increases the mental effort required to understand the codebase. Consistency reduces this burden and makes it easier for anyone to follow the logic.

## Scenario
Imagine you’re working on an e-commerce app, and you’ve been tasked with adding SMS and email notifications when an order is shipped. You notice the word “consignment” used throughout the codebase and assume this is the relevant concept. You begin searching for a `SendConsignment` method but can’t find it. Assuming no notification logic exists, you go ahead and implement a `SendConsignment` method along with the required dependencies and notification options.

Later, you open a pull request, and a colleague calls, confused, asking why you’ve re-implemented an entire feature. After some back and forth, they show you the existing `SendOrder` method, which already handles notifications.

:::bad
```csharp
public void SendOrder(NotificationType type)
{
// existing implementation
}
```
:::

## Outcome
What went wrong here? Was it a lack of diligence in searching for existing functionality, or the use of different terms — “order” and “consignment” — interchangeably? Likely a bit of both, but primarily, the issue is rooted in inconsistent terminology.

In this case, the terms “order” and “consignment” may seem related, but they have distinct meanings. An order is something a customer places, indicating their intent to purchase goods or services. A consignment, on the other hand, refers to what a supplier sends to a customer, which may partially or fully fulfill an order.

In this scenario, the `SendOrder` method should have been called `SendConsignment`, assuming “consignment” was already used in the codebase.

:::good
```csharp
public void SendConsignment(NotificationType type)
{
// new implementation
}
```
:::


To clarify, it's not necessarily wrong to have a `SendOrder` method, if the term order is ubiquitous. It might represent a pipeline for example, tracking a workflow from submission by the customer to receipt by the customer, and everything in between. But if “order” was the chosen term, the team should have used it consistently across the code. Any introduction of new terminology, such as “consignment,” should be a proactive, team-wide decision that includes any necessary refactoring.

## DRY Principle Implications
In a worst-case scenario, someone unfamiliar with the `SendOrder` method might merge the `SendConsignment` code without realizing it’s redundant. Now, two methods exist for the same function — each handling notifications differently. This violates the DRY principle, as you now have two distinct pieces of knowledge on handling order shipments, potentially leading to divergent behavior and increased maintenance overhead.
2 changes: 1 addition & 1 deletion rules/follow-naming-conventions/rule.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
seoDescription: Naming conventions are crucial to simpler code, and following established guidelines can make a significant difference in maintaining readability and scalability.
type: rule
archivedreason:
archivedreason: Superseeded by 9 individual rules
title: Do you follow naming conventions?
guid: 5bbf48f1-2e94-4e10-a520-6c4e39ba4522
uri: follow-naming-conventions
Expand Down
66 changes: 66 additions & 0 deletions rules/use-clear-meaningful-names/rule.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
---
seoDescription: Naming things is hard, but also important. Using clear, meaningful names will make your code more readable and reduce cognitive load and risk for your development team.
type: rule
archivedreason:
title: Do you use clear, meaningful names?
uri: clear-meaningful-names
created: 2024-11-05T00:00:00.0000000Z
authors:
- title: Matt Goldman
url: https://ssw.com.au/people/matt-goldman
related:
- nouns-for-class-names
- verbs-for-method-names
- avoid-generic-names
- avoid-micro-jargon
- consistent-words-for-concepts
- when-to-use-technical-names
- avoid-using-your-name-in-client-code
- use-meaningful-modifiers
- follow-naming-conventions-for-tests-and-test-projects
redirects:
- do-you-follow-naming-conventions
guid: bfcbc0ef-d2f8-4e77-85d9-97ccb841eb19
---

In the early days of coding, we had to store more information in our heads than in our computers, leading to all sorts of creative abbreviations and clever shortcuts. But today, storage and readability are no longer limitations—our computers can handle verbose names better than our brains can handle cryptic codes. Clinging to those old practices can hurt your code’s readability and make life harder for your team.

<!--endintro-->

## Avoid mental encoding
It’s easy to invent clever codes to keep names short, like `cstmrMgr` to represent a "customer manager." But using shorthand requires other developers (or your future self) to mentally decode each abbreviation, slowing comprehension and increasing the risk of misinterpretation. Instead, use instantly recognizable names — there’s no need to not simply call it `CustomerManager` (although there are reasons to avoid "manager" as a name, see our rule [Do you avoid generic names like “manager,” “processor,” “data,” or “info”?](/avoid-generic-names)).


## Be verbose
Today, there’s no reason to squeeze names into character limits or cryptic codes. While you shouldn’t use full sentences for a class or method name (test cases might be an exception, see our rule [Do you follow naming conventions for tests and test projects?](/follow-naming-conventions-for-tests-and-test-projects)), full, meaningful words make your code far more readable and maintainable.

:::bad
Imagine you’re creating a game and need a variable to store the player’s health. You might decide to use an integer called `NRG`. It’s short for "energy," which might seem clever — it’s easy to write, and you know what it means. But this has some problems:
* Other developers might misinterpret "energy" as something else, like power or ammo. Wouldn't "health" better represent the intended meaning here?
* If you add enemies with their own energy, what will you name their variable? (Spoiler: `nmeNrg`.)
:::

:::good
A better name for this variable is `PlayerHealth`. It clearly describes the specific kind of "energy" (health) and who it belongs to (the player), making it instantly understandable to anyone reading the code.
:::

:::bad
Now let’s say you’re working on an invitation and activation feature. You need a variable to store the validity period for an invitation, so you create one called: `ttlDays`.
While `ttlDays` might seem logical as shorthand for "time-to-live in days," other developers might interpret it as "total days," or spend extra time deciphering its intended use.
:::

:::good
Just call it `TimeToLiveInDays`. It leaves no room for misinterpretation and makes the purpose of the variable obvious on sight.
:::

:::bad
Consider a class named `UserValidator`. At first glance, it seems sensible — it’s presumably responsible for validating a user. But when you think about it, "UserValidator" doesn’t really tell us much. What exactly is it validating? Is it responsible for validating login credentials, profile information, or something else entirely?
:::

:::good
A clearer approach is to ensure each class has a specific responsibility. If it’s meant to handle all user-related validation rules, something like `ValidationHandler` indicates it’s an engine responsible for executing multiple rules and returning a result. But if the class is responsible for validating only a specific aspect of a user, a name like `UserNameLengthValidator` makes its role unmistakable; it tells us this class should validate only the length of a username.
:::

:::info
**Remember:** Names should describe what something represents without mental gymnastics to decode it. A clear, meaningful name is one of the simplest ways to make your code more readable, maintainable, and welcoming for future collaborators (and for yourself).
:::
Loading
Loading