Clean Code: A Handbook of Agile Software Craftsmanship

Category: Programming
Author: Robert C. Martin
4.5
All Stack Overflow 184
This Year Reddit 166
This Month Reddit 4

About This Book

Even bad code can function. But if code isn't clean, it can bring a development organization to its knees. Every year, countless hours and significant resources are lost because of poorly written code. But it doesn't have to be that way.

Noted software expert Robert C. Martin presents a revolutionary paradigm with Clean Code: A Handbook of Agile Software Craftsmanship . Martin has teamed up with his colleagues from Object Mentor to distill their best agile practice of cleaning code "on the fly" into a book that will instill within you the values of a software craftsman and make you a better programmer--but only if you work at it.

What kind of work will you be doing? You'll be reading code--lots of code. And you will be challenged to think about what's right about that code, and what's wrong with it. More importantly, you will be challenged to reassess your professional values and your commitment to your craft.

Clean Code is divided into three parts. The first describes the principles, patterns, and practices of writing clean code. The second part consists of several case studies of increasing complexity. Each case study is an exercise in cleaning up code--of transforming a code base that has some problems into one that is sound and efficient. The third part is the payoff: a single chapter containing a list of heuristics and "smells" gathered while creating the case studies. The result is a knowledge base that describes the way we think when we write, read, and clean code.

Readers will come away from this book understanding

  • How to tell the difference between good and bad code
  • How to write good code and how to transform bad code into good code
  • How to create good names, good functions, good objects, and good classes
  • How to format code for maximum readability
  • How to implement complete error handling without obscuring code logic
  • How to unit test and practice test-driven development

This book is a must for any developer, software engineer, project manager, team lead, or systems analyst with an interest in producing better code.

Comments

by uzomi   2019-08-24

Well, when talking about code maintainability it's not the same thing.

It's clear that both of you do not understand the concept of clean code. That's why you guys think that there is some language barrier that does not exist since you guys do not know what concept I'm talking about.

There is some stuff that's very valuable for every programmer to read and I recommend for you guys.

Clean Code

Working Effectively with Legacy Code

The SOLID principles

Those are very good books, give it a try and you might thank me later.

Have a nice day to you too Inukai!

by eggn00dles   2019-08-24

ahh hyperbole. always refreshing.

i'm saying to comment your code through clean naming conventions.

have you ever read just code and instantly understood what it did? it's a pretty cool experience.

https://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882/ref=sr_1_3?keywords=Clean+Code%3A+A+Handbook+of+Agile+Software+Craftsmanship&qid=1559240556&s=gateway&sr=8-3

id rather strive for beautiful explanatory code than crap up the code with verbose and often unclear or misleading comments.

comments can be counter-productive.

by the_real_chef   2019-08-24

Clean Code Books: - Clean Code: A Handbook of Agile Software Craftsmanship https://www.amazon.com/dp/0132350882/ref=cm_sw_r_cp_api_i_2k80CbD4F4QHJ - The Clean Coder: A Code of Conduct for Professional Programmers https://www.amazon.com/dp/0137081073/ref=cm_sw_r_cp_api_i_Ml80CbREG48TD

Design Patterns: - https://sourcemaking.com/design_patterns

And of course, good ol’ practice.

by slowfly1st   2019-07-21

Since it's only a few weeks and you will use Java primarily, probably look primarily at the Java API's / components:

https://docs.oracle.com/javase/8/docs/index.html

(honestly can't find this overview page for newer versions java)

Collections-API is a good start (Map, List, Collection and so on and their implementations), I/O (read and write files), Concurrency/Multithreading (also understand the concepts), JDBC (connect to a database, read and write data). Date/Time-API. Probably networking.

Also learn all the language features. E.g. that there are three different kind of comments, know "all the keywords" (what's volatile and transient? I always mix them up ...), or what is try-with-resource?

If you're decent with java, you'll have,... let's say "one problem less"

​

Learn OOP/OOD: Read and understand those concepts is a good start: SOLID, Loose coupling, High cohesion, Information Hiding. Those concepts we do apply, so we can reuse parts of our code (so it's not duplicated), improve maintainability, interchangeability (like changing the front end technology to display the website without redoing the whole software), and so on. Not sure if that's too early for you, in the sense, that you are still learning the language and learning another "thing" is too much.

​

Databases are already mentioned (many applications use a relational database as 'backend'): Setup a database (e.g. postgreSQL or mysql, both are free), learn how to create tables (columns, datatypes, primary keys, [indices, constraints]), crud operations (create, read, update, delete data), how to restrict selection of data (where clause), how "to join tables", functions (max(), avg(), count()). Imo the basic concepts of 'relational databases' and how you get/change data is quite easy compared to learning a programming language.

​

Read Clean Code. (Probably too early for you, but I leave it here)

​

Probably have a look at HTML/CSS/JS. I really like w3schools, but mostly as a reference, because I don't know these by heart. Not sure if you have enough time, but try to learn some of the components of html and learn how to style them. It's actually quite easy compared to Java. If there's enough time, to learn some JavaScript may be helpful, too.

​

... and now combine everything :P - no, seriously: "Ship" a product - even if it's something small and irrelevant. To break down a problem into smaller problems and combine everything we know to solve those problems with the most elegant solution is what we do day in day out. And get your code reviews (e.g. here on reddit, the stackexchange-network has a good code review network, too). Because there's always a better and more elegant solution. If no one tells you, your code sucks (... or can be improved) and why, you keep writing bad code - or at least you won't improve as fast.

by yankexe   2019-07-21

This is specific to JavaScript but I guess naming variables are the same across all the programming languages. Here's some insights from Clean Code book extracted for JavaScript.

Clean Code Naming Variables GitHub

by 00rb   2019-07-21

Refactoring guru is helpful: https://refactoring.guru/

Also, Clean Code: https://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882 by Martin.

As a junior dev you'll have plenty of time to learn as you go. But it would be a big plus knowing the stuff in advance.

by tannerz28   2019-07-21

I'll chime in since I'm writing a large-scale bot myself.

First of all, nice job so far. You are making good progress. I've checked on your repo occasionally within the last day, and see that you are continually making improvements. Keep it up!

My suggestion pertains to code style/readability.

  • Don't abbreviate your variable names if you can avoid it. For example, in your `random.js` file, you have this line:

js r = Math.random();

On other lines, it would be ambiguous as to what r represents. I'd recommend to always use descriptive identifiers, because it makes your code more readable and maintainable.

An easy fix for this would be to rename the variable to randomNumber. It only takes a second to type, but greatly reduces the amount of time it takes to understand your code.

Another example is in move.js where you have these two lines:

js h = false; // no text setting g = false; // no move

In theory, code should be "self-documenting", meaning you shouldn't need a comment to describe what a variable is. In this case, you added comments to basically describe the variable.

To resolve this, just change the variable to be the description of the variable, essentially, like:

js hasTextSetting = false hasMove = false

With a descriptive variable name (identifiers in general), there is no need to add a comment to describe what the variable does, because the identifier should tell you what it does or holds.

If you want to gain a lot of good coding habits, I would highly recommend reading Clean Code

Otherwise, it looks good so far. If you have any questions about making a bot or need help, feel free to ask me. Contact me on Discord, Joker#3650

by Shen_an_igator   2019-07-21

> Planning as much as you can before writing code

To add to that:

  1. Learn UML and how to draw activity diagrams. It takes forever at first but will cut your coding time down drastically + create code that is sensible instead of spaghetti code.

  2. Learn the conventions and symbols of UML. Not all of them are necessary, but the basics download here for free. Doesn't matter how long you worked in the industry, lacking this knowledge is detrimental to yourself, your employer, your project, and other coders that have to figure out your shit.

  3. Learn to cleancode before you tackle bigger projects (if you can't read your code like a book and you use variable names that are vague, your code is a mess) sadly I didn't find a good english source, but this book is the anchorpoint

  4. Learn how to create a game-design document. Fix what you want in your game. Once the document is finished, it's immutable. Until the game is done.

by mercsniper   2019-07-21

Also This https://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882

by anonymous   2019-07-21

Interesting! In Java as others said there is no limit (I never thought about the length!) but I think you want to avoid having a long method name as this could effect readability and even mental mapping (any other dev looking at the code may forget or want to forget the method name!).

I believe "clean code" in a nutshell talks about the use of descriptive pronounceable names. You could also argue a long descriptive name is better than a short one, I guess a sound balance. tis my humble view.

by anonymous   2019-07-21

It all depends on what you're application is doing and what the specific code is doing.

As thecoop says exceptions should be used for exceptional conditions. As an illustration take writing to a file. If checking for the existence of the file would slow your application down and/or the absence of the file is a serious problem then allow the exception to occur and trap that. If it's not so critical or recreating the file isn't a problem then do the file existence check first.

I've seen it argued that all error handling should be done via exceptions (most recently in Clean Code by Robert Martin) but I don't agree.

by anonymous   2019-07-21

To answer this is very hard as your code is a little confusing to look at, you need to remove some of your business logic and just include the code that effects the issue at hand.

I would highly recommend to read a book called: Clean Code by Robert C. Martin to improve your coding abilities. And for Android specifically I would recommend looking at this page. By cleaning your code and making it more modular and ordered, you'll be better equipped to debug and solve this problem yourself.

by DScratch   2019-07-21

Get comfortable with some of the current design patterns, MVP/MVVM. And try your best to stick to them, they really do help.

You don't have to stick to them at all times, but by the time you finish a feature you should have refactored to align yourself to them.

Simplified feature workflow would be like:

  • Design
  • Code
  • Test
  • Fix
  • Refactor
  • Test
  • git commit, push

​

And that's for every feature. You're not finished a feature 'til you've refactored it to meet your rules.

If you're having trouble sticking to them and you find yourself being like "Just this once* I can break a rule." Then a linter might help by throwing errors until you've cleaned up your code.

If you like reading then I can recommend 'Clean Code' by Uncle Bob. It really helped me improve my standards, and laid bare the importance of proper unit and integration testing.

by ziptofaf   2019-07-21

>All this is to say, my programs are very hard to follow and have random comments everywhere. Unless I'm wrong, refactoring is cleaning up code so it's readable and less complex, so how do I go about doing this?

I would suggest reading Clean Code, it's a great book that specifically showcases Java (but frankly it should be read by anyone sooner or later). It mentions A LOT of theory that goes into refactoring and writing readable and maintanable code while providing numerous code snippets. Now, considering that aforementioned book is 400 pages (and even that doesn't exhaust the topic), you can also imagine that any reddit style answer is going to be inadequate.

That being said, the general rules to follow:

  • proper variable naming. Be descriptive and specific in what they are doing. Eg. this is trash code:

​

bool chtUsrInList(array<array> list) {
  for u in list {
   if (i[1] == 1){return true;} 
  }
  return false;
}

You can't tell what this does. It also introduces magic numbers - what's the significance of 1 in array indexing or a value. Reworked version could look like so:

bool cheatingUserInList(array<array> userList) {
  userStatusRow = 1;
  cheatingStatus = 1;
  for user in userList {
   if (user[userStatusRow] == cheatingStatus){return true;} 
  }
  return false;
}

suddenly you can tell what this code is doing without any context. It's still not perfect (userStatusRow and cheatingStatus should probably be a part of User class of some kind) but it would work.

  • The optimal number of arguments for function to take is 0. Followed by 1. 2-3 arguments are also acceptable sometimes but they introduce way more options - suddenly order matters, you might need to look up the implementation multiple times to make sure you remember which is which etc. If you need more than 3 - time to rethink your idea or group multiple arguments together in some fashion. Be it by putting them in a class, a hash map, calling 2 separate functions etc etc.
  • Single Responsibility Principle. Each function and class has one responsibility. You probably don't want to have a class called TheInternet which handles requests from 10 different websites, parses the responses etc. Each website would get it's own little class, MAYBE after inheriting (or using interfaces) from something that lets you do basic HTTP requests.
  • This is counterintuitive but... every time you write a comment you essentially admit defeat. You claim "I couldn't write readable code so here's an explanation". You shouldn't explain WHAT the code is doing. I can see it in the code itself. You sometimes have to explain WHY the code is doing something and in some cases HOW is it doing it (in particular if it's a hard algorithm). Example from real application:

​

importProductsFromCatalogue(xlsx_file) {
...
// catalogue is maintained by humans and they sometimes forget about dots so instead of 20.5 you can end up with 205. 
// Decimals are not too important and no products should ever be heavier than 30kg. 
if (row[weight] > 30) {product.weight = 30;}
...
}

This explains WHY I do a specific action and that's it. In particular - remember that no comments is 100x better than misleading comments. And misleading comments are an easy thing to occur. They just need to become outdated and that's very simple to update the code without changing the comments.

  • Be consistent. Decide on a specific style of naming, commenting etc. Is 'get' the same thing as 'fetch'? Similar functions should have naming similar to each other. Don't introduce extra vocabulary unless there's a real difference in the usage.
  • Same abstraction level within a given function. Example:

​

//class User
bool isCorrect() {
return hasValidEmail && hasValidPassword && hasClickedOnValidationEmail
}

is fine. But:

bool isCorrect() {
special_characters = [',', '$', '%']
return hasValidEmail && this.password.length > 6 && this.password.include(special_characters) && hasClickedOnValidationEmail
}

is not. You now have two abstraction layers. One which is a very high level (hasValidEmail) and one that's far beneath it (manually checking if password is long enough and includes specific characters).

  • Write tests. This is IMHO the most important rule. Your code is considered broken as long as it doesn't have tests. Without them you cannot tell if your refactor doesn't break something elsewhere, you will be scared to change it. Write plenty of tests, test edge cases (eg. if a function works correctly with empty arrays if you pass one, whether or not it correctly checks first and last element in an array - off by one errors are super common after all) etc. This will save you countless hours that you would spend manually checking and troubleshooting later on. So if you want to do any major refactors - first make sure you have good testing coverage in place. Only then you can get to fiddling with code.
by anonymous   2019-07-21

Naming function and passing values to functions has always been one of many topics of discussion. I would recommend you to look at what's commonly called "Clean Code". It contains theory for naming and constructing functions. This is a good book to take a look at

http://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882

and check YouTube for Clean Code and you will probably find a few good talks.

My thoughts is that you can do a million different ways when constructing functions. You could, in theory, besides your examples have a function called Get that takes a pointer to a function that returns the type of the thing to get. But the only thing this adds is complexity. What we want to achieve is basically self commenting code that is easy for other people to read and understand. For this, every function should follow set rules in regards to how it is named in accordance to what it performs, what it is allowed to change and return etc. This would make for much easier code for someone to get into.

This goes for classes to. Don't have some class that sets up a million things in it's constructor. If that is needed, then create functions to encapsulate the behavior and call these functions from the constructor.

by anonymous   2019-07-21

Please note that there are more things to consider refactoring in your code, but here I will focus only on the boolean parameter smell.

You can refactor it by splitting up the method and deciding which one of the new methods to use at the place of invocation.

This will make your intention more clear at the point where you invoke either of the methods, especially if they have nice, descriptive names.

If I recall correctly, there is a section about it in Robert C. Martin's book: Clean Code: A Handbook of Agile Software Craftsmanship

public class className{
    public static void methodName1(Object atr1, Object atr2, Object atr3){
        encapsulation1(atr1, atr2, atr3);
        executeASingleInstruction();
        encapsulation2(atr1, atr2, atr3);
    }


    public static void methodName2(Object atr1, Object atr2, Object atr3){
        encapsulation1(atr1, atr2, atr3);
        // no execution of aforementioned instruction
        encapsulation2(atr1, atr2, atr3);
    }
}
by anonymous   2019-07-21

Actually this question is going to get closed because the answers will be opinion based and so is mine:

I would not go by Wordpress, the code of that project is... not good. WP is for sure not popular because of it's "superior" code and architecture. If you want a blog, take it, if you want good examples of development, architecture and best practice - stay far away from it.

PEAR is just outdated IMHO. And it is not just pear that has a code sniffer, phpcs is a generic tool:

https://github.com/squizlabs/PHP_CodeSniffer

Good projects come with a ruleset for their conventions. The sniffer itself comes bundled with a few rulesets like PEAR and I think PSR as well.

The PSR standard is a pretty good one to use except the never ending tab vs space discussion. I personally think spaces for indention over tabs is idiotic because that's exactly what tabs are thought for and virtually every editor can configure the displayed tab size to match X spaces.

So I would recommend the PSR standard.

But I use whatever standard the project I'm working on is using. If I work on CakePHP I use their coding standard, if I have to work on Wordpress (please no!), I'll use theirs. For my own projects I go for PSR.

I would recommend you to read this book in addition:

http://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882

It's using Java for the examples but the language doesn't really matter here.

Whatever standard you use, I'm happy you think about writing clean code and that you want to make sure you have a standard! Many "developers" just don't care and write a huge mess.

by tschellenbach   2019-07-12
This book is a great read for writing maintainable code: https://www.amazon.com/Clean-Code-Handbook-Software-Craftsma...
by raiflip   2019-07-12
Another few books I've found incredibly helpful: Clean Code: https://www.amazon.com/Clean-Code-Handbook-Software-Craftsma... Clean Architecture: https://www.amazon.com/Clean-Architecture-Craftsmans-Softwar... Domain Driven Design: https://www.amazon.com/Domain-Driven-Design-Tackling-Complex...
by CodeSheikh   2019-01-20
Nice list. Appreciate it. But I see there are a few amazing software books missing from the list such as:

- Clean Code (by "Uncle Bob")) [https://www.amazon.com/Clean-Code-Handbook-Software-Craftsma...]

- Design Patterns (by "Gang of 4") [https://www.amazon.com/Design-Patterns-Elements-Reusable-Obj...]

- Introduction to Algorithms (by "CLRS") [https://www.amazon.com/Introduction-Algorithms-3rd-MIT-Press...]