#begin

Today we are going to look at the next chapter of the Clean Code book by Robert C. Martin. In the previous blog entry of this series we discussed the first chapter of the book which is mainly about why this book is important, what clean code is, and what bad code is and it’s concequences.

In this next chapter we start diving into the practices to keep your code clean, or to transform and evolve bad code into clean code. It starts of with a very nice topic called “meaningful names” in my opinion. Since code is textual, naming things and making things read well is kind of important, don’t you think? Let’s take a look at the next chapter.

 

Meaningful Names

Let’s talk about meaningful names. We as authors of code, must create many identifiers for pieces of code. We name variables, functions, arguments to these functions, classes and folders or files and projects or components. Including many other Unity resources, things like, prefabs, textures, Scriptable Objects, models etc. You name it, no pun intended.

But, what is most important of a name in a software system? Well, I think an understandable and relatable name is very important. Also, you need the name to communicate the correct domain object and reach some consensus about it within your team or company, because for example a class called “Player” might mean different things. A player in a game might mean a user that is playing a game, or maybe a computer controlled player, or maybe even some kind of media player for video’s or audio or something.

So names need to be concise and fit properly within the domain. For this reason the Guru Uncle Bob listed a couple of guidelines about how to name things.

He starts off by saying that names need to reveal the intention of the thing it represents. So like I said, the name needs to fit the correct domain object. So for example if you have player class that exposes a function called “Damage” it does not really reveal what the damage function does. Does it calculate the damage? Subtract it? Applies the damage to something? Who knows? So renaming the function to something like TakeDamage is far more descriptive. If the TakeDamage function should be part of the Player class is a different discussion by the way. But, you know what I mean, name functions as the action they undertake.

Another example would be the magic algorithms you might sometimes find on StackOverflow that name everything by just a single character and smack everything down in 1 liners. So you have a function with a arguments called A, B and C for example, but that does not communicate very well, unless it fits within your domain but I highly doubt it.

There are also some generally accepted conventions you should follow. A very simply example is naming a boolean. These are often prefixed with “Is” or “Has” to indicate that it represents a boolean. So for example you should rename a flag called “Moving” to “IsMoving” or “Weapon” to “HasWeapon” or maybe “IsUnarmed”. Although naming things in a negated manner is bad practice too, we will talk about this a bit later. Some other prefixes you might see are get and set prefixes, although this relates more to Java than C#.

But always choose a name that reveals the intend of the thing you want to describe. We don’t want people to start guessing what it means, and then coming up with a faulty conclusion and thus introduce bugs. And sometimes it might take a while until you come up with a fitting name. I know I sometimes need a couple of iterations to come up with meaningful names. I mean, I might rename things multiple times before I check things in to Git. Luckily we have very powerful refactoring tools in our modern IDE’s. I hit SHIFT+F6 which is rename in Rider with Intellij shortcuts, I hit that shortcut very often!

The next piece of Uncle Bob’s advice is to avoid names that spread disinformation. That’s even worse right? I guess nowadays, that disinformation is a pretty loaded word. But nonetheless, disinformation sometimes accumulates in a project unknowingly by refactoring for example. Think about the following example.

You are writing a pooling system and you choose to represent the pool as an array. Maybe you added a fixed number of GameObjects as children of the pool parent and thus simply get them in the Awake by calling GetComponentsInChildren. You call this pool, PoolArray. Just pool would have been fine by the way and you would have avoided the problem I’m about to describe in the first place. But yeah, you called the thing poolarray. And then all is good until new requirements come in and you need the pool to be dynamic, so be able to grow and expand, like a List object. So you simply change the type of the PoolArray to List and add some logic to add and remove GameObjects from the pooling size. Yet, now you have a field called PoolArray, that is actually a List and this is what Uncle Bob means by disinformation.

And we all probably have seen or know many things like this in the code-base we are working in today. The same goes for using generally accepted names that are proposed by design patterns for something totally different. Imagine that someone names a class GameSingleton, yet it does not implement the singleton pattern. That would be very, very confusing. I’m not going into the problems of spreading singleton sprinkles all around your application just now, but just Imagine this scenario. You would always make false assumptions of a class called like this.

Disinformation can also be created by introducing names that are too long, or too similar. So let’s say we have an abstraction for persistence in our game. We implement both JSON and SQLite for example. We have two classes and they are called “MyAwesomePersistanceJSONSingleton” and “MyAwesomePersistenceSQLSingleton”. The chances someone is going to use the wrong class in this case can be pretty high since the names are this long and the difference between them is in the latter part of the name. You could rename them to let’s say: “JsonPersistence” and “SqlPersistence” respectively. Now, the thing that sets them apart is in the first part of the name plus the names are shorter and thus more readable. This will probably avoid some bugs in your game!

Then another interesting point Uncle Bob makes, which I have not really thought about much before is when you use a variable called I and the integer number 1, or a variable called o and integer number 0 in some algorithm. That this will increase the processing cost your brain has to do since you must distinct the I from 1 and o from 0. I think, in our modern IDE’s this is not much of a problem since variables and integers or constants are drawn in a different color nowadays. But I get if this was a problem in the early days. I think, if you edit the code in some random text editor without proper highlighting, let’s say notepad, please don’t do this.. get a proper ide… But you would have issues reading this and keeping things apart.

This is a bit of a Segway into the next things Uncle Bob proposes and that is to make meaningful distinctions between names. Imagine you have some game where you can get the active player. So you have a function called GetActivePlayer that returns a player object, but there’s also a function called GetActivePlayerInfo that also returns a player object. What do we use in this case? I don’t know. Maybe the function suffixed with Info used to return some scriptable object that defined some stats for the player like run speed and such. In this case the return value of the GetActivePlayerInfo should be changed to the PlayerInfo SO, or the function should simply be removed and all calls to it should be routed to the GetActivePlayer call since that is more descriptive.

There’s also other reasons why names can be distinct in weird manners and that’s simply by typo’s. We have probably all seen this before. A very concrete example I remember is that we were building a game which had inventory functionality. We build the thing ourselves, ofc because, we as game developers like building things like your own inventory systems. Every gamedev has probably done this once, or is currently planning to. So we build the thing but the old system we were replacing was not removed from the project because it was still used in some other parts. There was one flaw in our new inventory class and that was that it was spelled Invetnory instead of inventory and thus your intelli sense would always autocomple to the old inventory system which was really annoying. Luckily our IDE’s caught this error instantly but it was just really annoying. But what if we didn’t have the intellisense, would we have noticed? I think we would because there were different functions and data available in the new Inventory system but still, think about it. Fix typeos as soon as you catch them.

Then he also points out that noise words are meaningless for making distinctions like what is the difference between PlayerInfo and PlayerData for example. These suffixes are often just noise and thus can be removed. I do agree that in some cases it is useful to do this, like for example with Data Transfer Objects you would suffix them with Dto because then it is perfectly clear that these objects are transferred over the wire and a simply value objects instead of business objects.

And also don’t name things like DurationInt, just name it Duration! I mean, would Duration ever be a boolean or a string for example? We can discuss whether duration might be an int or a float for example, but overall, we know something called duration is most likely a number. So these suffices are just noise and should be removed. Like how would you know the difference between a class called Player or PlayerObject? If player in this case were some business entity, decoupled from unity and PlayerObject would be the GameObject that is shown in the scene. Please just remove the Object suffix and namespace them properly. This makes your code far more understandable.

Another attribute of a good name is that it is readable. We probably all know some class or function that uses weird acronyms all over the place. Imagine a class called “plyrbtnmgr” which stands for PlayerButtonManager. How would you communicate this with other developers on the team would you pronounce the full name, or would you yell this succession of weird acronyms through the office? Maybe they’ll even feel offended. Like hey Dave go plyrbtnmgr yourself. So try to avoid acronyms in names and just write things out. This will lead to name being a bit longer, but it makes them pronounceable which will improve communication. Also, if you find that when you write the full names instead of acronyms and the names become far too long. Well, maybe then it’s time to think of a different name all together.

Because if names are not well written and understood then searching for them, or understanding the code is difficult. This is notoriously with single letter names. Imagine that you have a member variable called “i” in a large class. This is horrible to read and find. There are exceptions to this rule of cource, like the Vector classes in Unity3D. They have variables called x, y and z because that’s part of the domain. So it’s pretty clear what they mean. But if you have a Player class with a variable called “p” for position then things start to become vague. Uncle bob has some great advice concerning one letter variables or fields and he says this and I quote: “The length of a name should correspond to the size of it’s scope”. So a short name is acceptable if the scope is small, and we require longer, more descriptive names when the scope is large.

And, you should also make sure to refactor out constant numbers or strings in algorithms or well, in your code in general. If you are for example rotating some object in the scene and you have something like: “transform.Rotate(Vector3.up* 5* Time.deltaTime);” rename the constant 5 to something like speed or speedmodifier. Another simple example is when you are doing things like localization, you know translating text to the correct language. You sometimes have specific pre or suffixes in localization keys. These constants should also be named, constant variables in your class somewhere. Because, first of all, you don’t you end up repeating them all over the place, and using a variable will be more readable since you add a small abstraction that way. And, the same goes for URL’s or accessing the file system for example.

Uncle Bob then also touches on a topic that I personally really get annoyed by sometimes and that is having meaningless member prefixes like the “ m_” prefix. We have all seen the code where something like a variable called name would be called m_name. This is just totally unnecessary with our modern IDE’s. Just follow the C# coding standards and call it _name. And yes, the _ prefix is pretty useful since, arguments in functions are all lower case as well. So if you have a function called SetName(string name) with an argument called name then, then if you prefix with _, you don’t have to use the “this” keyword in the function body. But yeah, you still don’t really need the _.

Another example of a generally accepted prefix is the I for interface. Uncle bob says that you can remove the I from the interface definition to for example Iplayer would simply become Player. And why? Well because you as a user of the interface should not care, or have to know you are working with a concrete class or an interface. And in this case, I disagree with the Guru and I’ll tell you why. Well, the prefixed I for interface has been there for a very long time. Changing this will just increase confusion in most situations. I remember discussing this with colleagues and they all wanted the I prefixed for interface because, that’s historically how it’s done. It’s still good to question these things because “we have always done it this way” is one of the worse answers you can get but we decided not to take this advice to fit the industry standard. Maybe if the defacto standard changes, we would remove the I prefix as well.

So let us then talk about class and method names since I see wrongly named classes and function as well. On the forums for example. Classes should always be nouns like: Player, User, Enemy, Weapon, Chest, they should not be verbs. Also, a class is always singular, so don’t call your class Enemies, or Bullets. In this case, maybe EnemyPool or BulletPool might be better. If you need to express something that’s a plural try to boil it down to a single entity. This can sometimes be difficult but, yeah the act of renaming takes no effort in mordern IDE’s, so try a couple of nouns and see what fits best.

Method names on the other hand should always be verbs like “ApplyDamage” or “Move” and I know, Move can both be a noun and a verb but the context is probably known. And then again, try to make the verb fitting for the action that is going to be undertaken. Also, consider side-effects made by the function if there are any. So for example, if you have a function that updates a username, but also writes it to a database or back-end add that in your function name. It would still be better to separate these calls but still rename a function of this sort from UpdateName to UpdateNameAndSave. I know this is very ugly but it communicates the intent very well and this will probably motivate you to separate the name update and persistence logic. But we’ll talk more about functions and side-effects later.

Then something else I also sometimes see in code is people trying to be funny with the names. And, yes I’ve done this myself with a class. We were making a VR game and we had these async commands called jobs. And well, in VR you have the concept of Hands, so you fill in the blanks. We had a good laugh about it but it probably did not communicate the intent of the job very well. The fact that I cannot remember what exactly it did proves as much. So, you probably know variables, function or classes with funny names like wrapping the Destroy calls for GameObjects in functions “HangMySelf” or something. Don’t do it.

Next Uncle Bob tells us to stick with once word per concepts. Don’t use names like manager or controller to mean the exact same domain object. This will confuse people. I mean, what is the difference between managers and controllers anyway? According to the mirriam-webster dictionary a controller is something that has authority to control and a manager is someone who directs a team. So there is a distinct difference between a controller and a manager, I mean, the controller has authority to force things, but a manager just facilitates. So, are we actually this precise when it comes to naming things in code? Well, I wouldn’t go this way since it will probably confuse people. Yet, if there controller and managers are distinct concepts in your domain model, you can use them ofc, but I highly doubt it.

Next, although I think we touched upon this topic already is to use solution domain names. Like, if you have a class that represents a Queue, call it that way. For example, in a multiplayer FPS game if you some kind of queue for respawning after you got fried. Call the class, RespawnQueue, to indicate that it is an actual Queue object. This will increase the understandability of the code. The same goes for other kinds of solution domain objects like Stacks, Visitors, and even design patterns like AbstractFactory for example.

And, lastly. Please avoid meaningless Prefixes to indicate things belonging some project. The obvious example that comes to mind here is the Text Mesh Pro implementation in Unity3D. The annoying TMP_ prefix is totally unnecessary. I can’t really remember if they had this before they got acquired by Unity, so they may have done this for backwards compatibility reasons to avoid conflicts. But, they can remove it in some later version if it were up to me. Just, in the next major release, where breaking changes are generally accepted, remove the prefix and be done with it. I’ll gladly refactor my code a bit to remove all the prefixes 🙂

So that’s it for the second part of this blog. The next blog will cover the third chapter of the book called Functions. I hope you gained some new information or some of your existing knowledge has been refreshed. And Also, if you would like to help me, please let me know if you like the specific examples I gave in this blog. I know they are all related to Unity3D, which might be new or unknown to you but generally these things can be applied without Unity3D as well. I’m just corious if I picked and explained examples well enough.

Thanks for reading, and smell you next time!

#end

01010010 01110101 01100010 01100101 01101110.

Hey, sorry to bother you but you can subscribe to my blog here.

Never miss a blog post!

You have Successfully Subscribed!