Cle·an Co·de
/kliːn koʊd/
Oh God! He’s talking about cleaning his codes now! What a madlad!
Hey, I heard that! By the way, it’s been a few weeks already since I started, so I’m going to talk about something that should be essential at coding/developing, which is “Clean Code”. Most developer teams practice this already on their project, however, it’s a good thing to address and discuss, as there are some who still haven’t practiced it.
Clean Code
free from dirt, marks, or stains.
program instructions.
Going on a literal sense from the dictionary, a “Clean Code” would mean “Program instructions that is free from dirt, marks, or stains”. While it is accurate to a sense, we still have to explain what makes it “free from dirt, marks, or stains”.
Different people have different standards. I could make my codes as clean and elegant as possible, if I don’t follow some kind of a guide, I would never get some people’s approval and my codes won’t ever be actually “clean”. Thankfully, lots of intellectuals have banded together and talked about what counts as a Clean Code. While they still share their own views about it, it’s something that the general public has accepted as something that is “Clean”.
What Is Clean Code?
As Bjarne Stroustrup, inventor of C++ said:
I like my code to be elegant and efficient. The logic should be straightforward to make it hard for bugs to hide, the dependencies minimal to ease maintenance, error handling complete according to an articulated strategy, and performance close to optimal so as not to tempt people to make the code messy with unprincipled optimizations. Clean code does one thing well.
As expected from a master of the language arts. Mr. Stroustrup focuses mainly on elegance and efficiency. While Grady Booch, author of Object Oriented Analysis and Design with Applications have this opinion about clean code:
Clean code is simple and direct. Clean code reads like well-written prose. Clean code never obscures the designer’s intent but rather is full of crisp abstractions and straightforward lines of control.
And finally, “Big” Dave Thomas, founder of OTI, godfather of the Eclipse strategy said:
Clean code can be read, and enhanced by a developer other than its original author. It has unit and acceptance tests. It has meaningful names. It provides one way rather than many ways for doing one thing. It has minimal dependencies, which are explicitly defined, and provides a clear and minimal API. Code should be literate since depending on the language, not all necessary information can be expressed clearly in code alone.
From those three perspectives, there’s a lot of things that we can classify as “Clean Codes”. But with those explanations, there are at least a few aspects of Clean Codes that we can break and clarify. Here, we can clarify the characteristics of clean codes as follows:
- Elegant : It should be pleasing to read. Reading it should make you smile stretched from ear to ear, the same way you would when you see your special someone, or the same way you would when you find that special thing you’ve been searching for.
- Readability : Clean code should read like well-written prose. Each function, each class, each module exposes a single-minded attitude that remains entirely undistracted, and unpolluted, by the surrounding details.
- Simple : Do one thing with the Single Responsibility Principle ( a computer programming principle that states that every module, class, or function should have responsibility over a single part of the functionality provided by the software, and that responsibility should be entirely encapsulated by the class, module or function). Everything is kept simple and orderly, appropriate attention to details have been paid.
- Testable : Run all tests. It should be tested out fully.
While there are still some characteristics that we haven’t quite gotten in to (like how it shouldn’t have repetitions or duplication), these four characteristics are the four main aspects that we need to look out for when we want to implement Clean Code in our project. While we review our codes, it is wise to compare them to the four aspects we have here, and make sure our codes fit into all of these aspects to make sure we fully scrubbed our code clean!
Do’s And Don’ts
Now that we have learnt the basic characteristics of Clean Code, we can converse in the various Do’s that we can do with Clean Code, as well as the Don’ts. That’s precisely what I’m doing now, can’t you see?
Do : Meaningful Names
When we just started coding, it’s okay to, for example, use the names “int d” or “String s”, as we were just learning then, we were working on small projects of our own, not bigger ones where we collaborate with various people. And I’m here to show you why those kind of names don’t work! Consider the following :
int d; // d = amount of rewinds
Without the comments, would we be able to understand what “d” means?? No, no we wouldn’t (Not unless we’re the developer who wrote that though). Now consider the following :
String message;
For those kinds of code, we don’t even need a comment for context as the object name itself already explained what it is. This is why we better use meaningful names in our project as much as possible. This is also done to minimize the comment writing, as longer comments would provide in less-productivity.
Don’t : Mental Map
Readers shouldn’t have to mentally translate your names into other names they already know. This problem generally arises from a choice to use neither problem domain terms nor solution domain terms. One difference between a smart programmer and a professional programmer is that the professional understands that clarity is king. Professionals use their powers for good and write code that others can understand. Let me show you something :
# bad
a = get_apple()
o = get_orange()
s = make_smoothie(a, o)
While it is descriptive (get_apple(), make_smoothie(a, o)) those two refers to the actual functions. The term “a”, “o”, and “s” are too horrible for codes. It only seems to substitute speed for readability, and that is a bad thing to do on a code. As bad readability means worse speed if we don’t catch on fast. Now, I propose something else :
# good
apple = get_apple()
orange = get_orange()
smoothie = make_smoothie()
These are the exact same as the one above it, except that it explains it all. It’s amazing how adding just a few more alphabets into an object can make it way more readable. It is generally bad to mental map, as not everyone have the same way of thinking you do. Therefore, it is best to explain it all.
Do : One Thing
Following the Single Responsibility Principle (SRP):
Functions should do one thing. They should do it well. They should do it only.
What does this mean? It literally means what it means: Functions should do just one thing and do it loud and clear. You don’t expect a hair-dryer to freeze your hair, do you? Or your kid’s doll to do your taxes? Each and every function have their own individual function, so they should do it well.
For example:
Let’s assume we need an object to keep an email message. Our IEmail interface and Email class have 2 responsibilities. If we keep only one class, each change for a responsibility might affect the other one.
// single responsibility principle - bad example
interface IEmail {
public void setSender(String sender);
public void setReceiver(String receiver);
public void setContent(String content);
}
class Email implements IEmail {
public void setSender(String sender) {// set sender; }
public void setReceiver(String receiver) {// set receiver; }
public void setContent(String content) {// set content; }
}
We can create a new interface and class called IContent and Content to split the responsibilities. Having only one responsibility for each class give us a more flexible design.
// single responsibility principle - good example
interface IEmail {
public void setSender(String sender);
public void setReceiver(String receiver);
public void setContent(IContent content);
}
interface Content {
public String getAsString(); // used for serialization
}
class Email implements IEmail {
public void setSender(String sender) {// set sender; }
public void setReceiver(String receiver) {// set receiver; }
public void setContent(IContent content) {// set content; }
}
Don’t : Repeat Yourself
Ah, DRY. No, not keeping your clothes DRY or the likes. DRY is an abbreviation, DRY : Don’t Repeat Yourself. Duplication is a problem in software. Many principles and best practices have been created to reduce duplication code. As said before, repetition is not nice, let alone duplication. That’s why DRY is a good concept to hold on to when implementing clean code.
Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.
Every duplicate line into application needs to be maintained. If a potential source of bugs appear, it would have to be fixed in all of those duplicates. It bloats the codebase making it much more difficult for developers to fully understand the entire system.
Principles
While there are a lot we’ve covered, there’s actually something that I forgot to mention, which is the Clean Code Principles. While the Principles are created by a group of developers with their own perspectives, the Principles used are widely well-received by the IT-Community, which is why it holds true until now. Actually, I’ve talked about one of the principles already, specifically DRY (Don’t Repeat Yourself). The rest of the principles are as follows:
KISS: Keep It Simple Stupid. A design principle originating from the U.S. Navy that goes back to 1960 already. It states that most systems should be kept as simple as possible (but not simpler, as Einstein would have said). Unnecessary complexity should be avoided. The question to ask when you’re writing code is “can this be written in a simpler way?”
DRY: Don’t Repeat Yourself. I’ve actually explained a bit about DRY above. It is closely related to KISS and the minimalist design philosophy. Violations of DRY are referred to as WET: We Enjoy Typing, Write Everything Twice, Waste Everyone’s Time.
YAGNI: You Aren’t Gonna Need It. A developer should not add functionality unless deemed necessary. YAGNI is part of the Extreme Programming (XP) methodology, which wants to improve software quality and increase responsiveness to customer requirements. YAGNI should be used in conjunction with continuous refactoring, unit testing, and integration.
Composition Over Inheritance: Not an acronym, sadly. It’s a principle where you design your types over what they do instead of over what they are. Composition is favored over inheritance by many developers, because inheritance forces you to build a taxonomy of objects early on in a project, making your code inflexible for changes later on.
Favor readability: It’s not because a machine can read your code that another human can. Particularly when working with multiple people on a project, always favor readability over conciseness. There’s no point in having concise code if people don’t understand it.
Conclusion
Whoa, didn’t know we could get so much into clean code that fast. Well that is basically what we need to know about clean codes. The most important thing to do is staying true to the characteristics. And following the principles specified would make you walk closer to the glorious path of Clean Code-ism. Well, that’s about it for Clean Code. It’s me, signing off.
Adeus~