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 5

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 restlessapi   2019-11-17

>What are your favorite resources out there that you turn to, that could be helpful in showing someone what a good review is?

Clean Code by Robert C. Martin.

This book covers all kinds of great stuff regarding correctness, maintainability, testability, etc.

I want to call your attention to something you wrote though.

>mid level engineers spending lot of time arguing about things that should not be the focus of the code reviews - e. g. variable names, code styles etc. In doing so, they are also not paying enough attention to the overall architecture, correctness, maintainability, testability etc. for the code they are reviewing.

This is a false dichotomy. Having code with well thought out names and formatting, enables having maintainable and testable code. It makes reasoning about correctness much easier. Same is true for the overall architecture. I would go so far as to say, you cannot have all of the attributes you desire, without having code that is easy to read.

Now, mid level devs are notorious for taking "Clean Code" too far, and inciting holy wars to purge the heathen sinners who dont conform 100%. Perhaps they just need their zealotry toned down. Names and formatting are definitely important, but not so important that they cant see the forest for the trees.

by zintjr   2019-11-17

Also your methods are way too long!

  • Main - 36 lines long
  • WeekdaysBetweenTwoDates - 37 lines long
  • BusinessDaysBetweenTwoDates - 91 lines long

​

So how long should they be? That is subjective. Some say as short as possible (around 5 lines long) others say no more than 20 lines long. Personally I think if you shoot for somewhere between 12-18 lines long you're ok. But for sure anything over 20 lines long you should probably start breaking up the logic into other methods.

​

Don't feel bad we all started out the same way. Read "Clean Code" to learn better coding techniques. Good luck!

by UnobtrusiveHippo   2019-11-17

If you forced me to pick a book: Don't Make Me Think is pretty important.

​

I would agree you don't really want a book to get started. Things change really fast in the web so the books you want to invest in are going to be more theory based rather than technology based, because the technologies that are being used right now can be phased out in a year or two.

You want to just get something up and running. Once you get comfortable with some basics you can dive deeper.

​

I like this course for getting ramped up https://www.udemy.com/the-web-developer-bootcamp/learn/lecture/3861606?start=0#overview

Usually these course creators continue to update to keep with the times so you won't learn anything too outdated. He has an "advanced" one also.

​

Two books I've heard are great but honestly I haven't read yet are: Clean Code and The Pragmatic Programmer

by rdmeneze   2019-11-17

I recommend you to read the book Clean Code (https://www.amazon.de/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882). There are a lot of tips on writing code that can be read by other people, like you eight months in the future.

by KoleCasule1   2019-11-17

This is the third book suggested that was written by Uncle Bob.

Can you maybe explain the Difference between:

Clean Code , Clean Architecture and Clean Coder. All books by Uncle Bob

by siphilis   2019-11-17

It sounds like you could really benefit from reading Clean Code. It isn't really about a specific design pattern, but an overall design philosophy. It gets mentioned in the programming subreddits all the time, and for good reason. I haven't finished it yet, but it's already had a big positive impact on the way I think about, and design my code.

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.