Should class names really be nouns? Rethinking the classics
Tags: oop, programming, discuss, dart
Published: 2022-12-27 11:35:18

## The problem

One of the most fundamental ways of thinking in terms of Object Oriented Programming is thinking in objects. Does this look familiar?

```dart
class Dog {
	bark();

	waveTail();
}
```

Sadly, in programming we rarely actually use nouns. We usually operate via verbs.

For example, Repository names should not be written via nouns. Next code example is written via nouns and it breaks SOLID principles:

```dart
class ChatsRepository {
	getChat();

	getChats();

	updateChat();

	deleteChat();
}	
```

Here is the fixed version. This code does not break SOLID:

```dart
class ChatGetterRepository {
	getChat();
}

class ChatsGetterRepository {
	getChats();
}

class ChatUpdaterRepository {
	updateChat();
}

class ChatDeleterRepository {
	deleteChat();
}
```

But this code is still far from being perfect. Can you name the problem with it?

Programmers usually spend 90% of their time actually reading the code not writing it (source: Clean Code by Robert C. Martin). Thus the easier it is to read the code the less time you will spend on adding features and fixing bugs.

Now we come to an important question: what code is easy to read and what is hard to read? Well, interesting thing about reading is the fact that we internally pronounce code while we read it. And if code is easy to pronounce then it is easy to read (source: also Clean Code by Robert C. Martin).

Try to read out loud these 2 class names:  `ChatDeleter` and `DeleteChat`. Obviously, second one is easier on the tongue. The first one is too clunky. `Cha-t-de-le-te-r` vs `De-le-te-cha-t`.

On top of that it is important to use words that we actually use in real life. Because the code should not be cryptic. The code is written for humans to understand not for the machines. The machines do not care if we name our class `x`, `y`, `ChatDeleter`, or `MegaUltraZoomZoomChatDeleterAgentRepositoryClass9000`. We write code programmers. For our fellow humans. For our selfs. So why on earth do we name our classes so alien and cryptic? Why do we write things like `ChatDeleter` instead of `DeleteChat`? Have ever tried to describe your code to your teammate?

-Hey, team mate! What are you working on? What do you want to do?

Compare these answers:

-Hey! I want to use chat repository to delete a chat.
-Hey! I want to use chat deleter to delete a chat.
-Hey! I want to delete a chat.

I think it goes without saying that first two answers are just plain weird. Yet these is exactly how we write code. We simply have been doing it for so long that we don’t even see the problem anymore.

## The solution

The solution is quite simple: we need to use verbs instead of nouns for naming our classes.

Here are our new classes:

```dart
class GetChatRepository {
	getChat();
}

class GetChatsRepository {
	getChats();
}

class UpdateChatRepository {
	updateChat();
}

class DeleteChatRepository {
	deleteChat();
}

// Example usage:
DeleteChatRepository().deleteChat();
```

Some languages even allow us to avoid code duplication by using conventions. Java has `main()` method, Dart has `call()` and Go has… well, `go()`.

```dart
class GetChatRepository {
	call();
}

class GetChatsRepository {
	call();
}

class UpdateChatRepository {
	call();
}

class DeleteChatRepository {
	call();
}
// Example usage:
DeleteChatRepository().call();
// Dart allows us to have a shortcut:
DeleteChatRepository()();
```

If you are still not convinced that nouns are the way to go let me demonstrate a typical code that uses Dependency Injection:

```dart
// Example of DI using nouns.
class ChatDeleter {
	// Next two lines represent the way Dependency injection usually works in Dart.
	final ChatDeleterRepository chatDeleterRepo;
	const DeleteChatUseCase({required this.chatDeleterRepo});

	deleteChat() {
		chatDeleterRepo.deleteChat();
	}
}

ChatDeleterUseCase().deleteChat();

// Example of DI using verbs.
class DeleteChat {
	// Next two lines represent the way Dependency injection usually works in Dart.
	final DeleteChatRepository deleteChat;
	const DeleteChatUseCase({required this.deleteChat});

	call() {
		deleteChat();
	}
}

DeleteChat()();
```

## Why it is important

If code is not written in plain english and you need to do any kind of mental transformation or guess work then it is not readable code. It is a structured mess.

The sad thing is classes are the most fundamental thing we use. This means that we constantly mentally jump through hoops by doing guess work, mental transformation and internally pronouncing unreadable words. It is an invisible perpetual torture.