├── LICENSE └── README.md /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Leonardo Bernardes 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # clean-code-java 2 | 3 | ## Table of Contents 4 | 1. [Introduction](#introduction) 5 | 2. [Variables](#variables) 6 | 3. [Functions](#functions) 7 | 4. [Objects and Data Structures](#objects-and-data-structures) 8 | 5. [Classes](#classes) 9 | 6. [SOLID](#solid) 10 | 7. [Testing](#testing) 11 | 8. [Concurrency](#concurrency) 12 | 9. [Error Handling](#error-handling) 13 | 10. [Formatting](#formatting) 14 | 11. [Comments](#comments) 15 | 12. [Translation](#translation) 16 | 17 | ## Introduction 18 | ![Humorous image of software quality estimation as a count of how many expletives 19 | you shout when reading code](http://www.osnews.com/images/comics/wtfm.jpg) 20 | 21 | Software engineering principles, from Robert C. Martin's book 22 | [*Clean Code*](https://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882), 23 | adapted for Java. This is not a style guide. It's a guide to producing 24 | [readable, reusable, and refactorable](https://github.com/ryanmcdermott/3rs-of-software-architecture) software in Java. 25 | 26 | Not every principle herein has to be strictly followed, and even fewer will be 27 | universally agreed upon. These are guidelines and nothing more, but they are 28 | ones codified over many years of collective experience by the authors of 29 | *Clean Code*. 30 | 31 | Our craft of software engineering is just a bit over 50 years old, and we are 32 | still learning a lot. When software architecture is as old as architecture 33 | itself, maybe then we will have harder rules to follow. For now, let these 34 | guidelines serve as a touchstone by which to assess the quality of the 35 | Java code that you and your team produce. 36 | 37 | One more thing: knowing these won't immediately make you a better software 38 | developer, and working with them for many years doesn't mean you won't make 39 | mistakes. Every piece of code starts as a first draft, like wet clay getting 40 | shaped into its final form. Finally, we chisel away the imperfections when 41 | we review it with our peers. Don't beat yourself up for first drafts that need 42 | improvement. Beat up the code instead! 43 | 44 | ## **Variables** 45 | ### Use meaningful and pronounceable variable names 46 | 47 | **Bad:** 48 | ```java 49 | String yyyymmdstr = new SimpleDateFormat("YYYY/MM/DD").format(new Date()); 50 | ``` 51 | 52 | **Good:** 53 | ```java 54 | String currentDate = new SimpleDateFormat("YYYY/MM/DD").format(new Date()); 55 | ``` 56 | **[⬆ back to top](#table-of-contents)** 57 | 58 | ### Use the same vocabulary for the same type of variable 59 | 60 | **Bad:** 61 | ```java 62 | getUserInfo(); 63 | getClientData(); 64 | getCustomerRecord(); 65 | ``` 66 | 67 | **Good:** 68 | ```java 69 | getUser(); 70 | ``` 71 | 72 | 73 | **[⬆ back to top](#table-of-contents)** 74 | 75 | ### Use searchable names 76 | We will read more code than we will ever write. It's important that the code we 77 | do write is readable and searchable. By *not* naming variables that end up 78 | being meaningful for understanding our program, we hurt our readers. 79 | Make your names searchable. 80 | 81 | **Bad:** 82 | ```java 83 | // What the heck is 86400000 for? 84 | setTimeout(blastOff, 86400000); 85 | 86 | ``` 87 | 88 | **Good:** 89 | ```java 90 | // Declare them as capitalized `const` globals. 91 | public static final int MILLISECONDS_IN_A_DAY = 86400000; 92 | 93 | setTimeout(blastOff, MILLISECONDS_IN_A_DAY); 94 | 95 | ``` 96 | **[⬆ back to top](#table-of-contents)** 97 | 98 | ### Use explanatory variables 99 | **Bad:** 100 | ```java 101 | String address = "One Infinite Loop, Cupertino 95014"; 102 | String cityZipCodeRegex = "/^[^,\\\\]+[,\\\\\\s]+(.+?)\\s*(\\d{5})?$/"; 103 | 104 | saveCityZipCode(address.split(cityZipCodeRegex)[0], 105 | address.split(cityZipCodeRegex)[1]); 106 | ``` 107 | 108 | **Good:** 109 | ```java 110 | String address = "One Infinite Loop, Cupertino 95014"; 111 | String cityZipCodeRegex = "/^[^,\\\\]+[,\\\\\\s]+(.+?)\\s*(\\d{5})?$/"; 112 | 113 | String city = address.split(cityZipCodeRegex)[0]; 114 | String zipCode = address.split(cityZipCodeRegex)[1]; 115 | 116 | saveCityZipCode(city, zipCode); 117 | 118 | ``` 119 | **[⬆ back to top](#table-of-contents)** 120 | 121 | ### Avoid Mental Mapping 122 | Don’t force the reader of your code to translate what the variable means. 123 | Explicit is better than implicit. 124 | **Bad:** 125 | ```java 126 | String [] l = {"Austin", "New York", "San Francisco"}; 127 | 128 | for (int i = 0; i < l.length; i++) { 129 | String li = l[i]; 130 | doStuff(); 131 | doSomeOtherStuff(); 132 | // ... 133 | // ... 134 | // ... 135 | // Wait, what is `$li` for again? 136 | dispatch(li); 137 | } 138 | ``` 139 | 140 | **Good:** 141 | 142 | ```java 143 | String[] locations = {"Austin", "New York", "San Francisco"}; 144 | 145 | for (String location : locations) { 146 | doStuff(); 147 | doSomeOtherStuff(); 148 | // ... 149 | // ... 150 | // ... 151 | dispatch(location); 152 | } 153 | ``` 154 | **[⬆ back to top](#table-of-contents)** 155 | 156 | ### Don't add unneeded context 157 | If your class/object name tells you something, don't repeat that in your 158 | variable name. 159 | 160 | **Bad:** 161 | ```java 162 | class Car { 163 | public String carMake = "Honda"; 164 | public String carModel = "Accord"; 165 | public String carColor = "Blue"; 166 | } 167 | 168 | void paintCar(Car car) { 169 | car.carColor = "Red"; 170 | } 171 | ``` 172 | 173 | **Good:** 174 | ```java 175 | class Car { 176 | public String make = "Honda"; 177 | public String model = "Accord"; 178 | public String color = "Blue"; 179 | } 180 | 181 | void paintCar(Car car) { 182 | car.color = "Red"; 183 | } 184 | ``` 185 | **[⬆ back to top](#table-of-contents)** 186 | 187 | ## **Functions** 188 | ### Function arguments (2 or fewer ideally) 189 | Limiting the amount of function parameters is incredibly important because it 190 | makes testing your function easier. Having more than three leads to a 191 | combinatorial explosion where you have to test tons of different cases with 192 | each separate argument. 193 | 194 | One or two arguments is the ideal case, and three should be avoided if possible. 195 | Anything more than that should be consolidated. Usually, if you have 196 | more than two arguments then your function is trying to do too much. In cases 197 | where it's not, most of the time a higher-level object will suffice as an 198 | argument. 199 | 200 | 201 | **Bad:** 202 | 203 | 204 | **Good:** 205 | 206 | **[⬆ back to top](#table-of-contents)** 207 | 208 | 209 | ### Functions should do one thing 210 | This is by far the most important rule in software engineering. When functions 211 | do more than one thing, they are harder to compose, test, and reason about. 212 | When you can isolate a function to just one action, they can be refactored 213 | easily and your code will read much cleaner. If you take nothing else away from 214 | this guide other than this, you'll be ahead of many developers. 215 | 216 | **Bad:** 217 | ```java 218 | public void emailClients(List clients) { 219 | for (Client client : clients) { 220 | Client clientRecord = repository.findOne(client.getId()); 221 | if (clientRecord.isActive()){ 222 | email(client); 223 | } 224 | } 225 | } 226 | ``` 227 | 228 | **Good:** 229 | ```java 230 | public void emailClients(List clients) { 231 | for (Client client : clients) { 232 | if (isActiveClient(client)) { 233 | email(client); 234 | } 235 | } 236 | } 237 | 238 | private boolean isActiveClient(Client client) { 239 | Client clientRecord = repository.findOne(client.getId()); 240 | return clientRecord.isActive(); 241 | } 242 | ``` 243 | 244 | **[⬆ back to top](#table-of-contents)** 245 | 246 | ### Function names should say what they do 247 | 248 | **Bad:** 249 | ```java 250 | private void addToDate(Date date, int month){ 251 | //.. 252 | } 253 | 254 | Date date = new Date(); 255 | 256 | // It's hard to to tell from the method name what is added 257 | addToDate(date, 1); 258 | ``` 259 | **Good:** 260 | ```java 261 | private void addMonthToDate(Date date, int month){ 262 | //.. 263 | } 264 | 265 | Date date = new Date(); 266 | addMonthToDate(1, date); 267 | ``` 268 | 269 | **[⬆ back to top](#table-of-contents)** 270 | 271 | ### Functions should only be one level of abstraction 272 | When you have more than one level of abstraction your function is usually 273 | doing too much. Splitting up functions leads to reusability and easier 274 | testing. 275 | 276 | **Bad:** 277 | 278 | 279 | **Good:** 280 | 281 | **[⬆ back to top](#table-of-contents)** 282 | 283 | ### Remove duplicate code 284 | Do your absolute best to avoid duplicate code. Duplicate code is bad because it 285 | means that there's more than one place to alter something if you need to change 286 | some logic. 287 | 288 | Imagine if you run a restaurant and you keep track of your inventory: all your 289 | tomatoes, onions, garlic, spices, etc. If you have multiple lists that 290 | you keep this on, then all have to be updated when you serve a dish with 291 | tomatoes in them. If you only have one list, there's only one place to update! 292 | 293 | Oftentimes you have duplicate code because you have two or more slightly 294 | different things, that share a lot in common, but their differences force you 295 | to have two or more separate functions that do much of the same things. Removing 296 | duplicate code means creating an abstraction that can handle this set of 297 | different things with just one function/module/class. 298 | 299 | Getting the abstraction right is critical, that's why you should follow the 300 | SOLID principles laid out in the *Classes* section. Bad abstractions can be 301 | worse than duplicate code, so be careful! Having said this, if you can make 302 | a good abstraction, do it! Don't repeat yourself, otherwise you'll find yourself 303 | updating multiple places anytime you want to change one thing. 304 | 305 | **Bad:** 306 | 307 | 308 | **Good:** 309 | 310 | **[⬆ back to top](#table-of-contents)** 311 | 312 | ### Set default objects with Object.assign 313 | 314 | **Bad:** 315 | 316 | **Good:** 317 | 318 | **[⬆ back to top](#table-of-contents)** 319 | 320 | 321 | ### Don't use flags as function parameters 322 | Flags tell your user that this function does more than one thing. Functions should do one thing. Split out your functions if they are following different code paths based on a boolean. 323 | 324 | **Bad:** 325 | 326 | 327 | **Good:** 328 | 329 | **[⬆ back to top](#table-of-contents)** 330 | 331 | ### Avoid Side Effects (part 1) 332 | A function produces a side effect if it does anything other than take a value in 333 | and return another value or values. A side effect could be writing to a file, 334 | modifying some global variable, or accidentally wiring all your money to a 335 | stranger. 336 | 337 | Now, you do need to have side effects in a program on occasion. Like the previous 338 | example, you might need to write to a file. What you want to do is to 339 | centralize where you are doing this. Don't have several functions and classes 340 | that write to a particular file. Have one service that does it. One and only one. 341 | 342 | The main point is to avoid common pitfalls like sharing state between objects 343 | without any structure, using mutable data types that can be written to by anything, 344 | and not centralizing where your side effects occur. If you can do this, you will 345 | be happier than the vast majority of other programmers. 346 | 347 | **Bad:** 348 | 349 | 350 | **Good:** 351 | 352 | **[⬆ back to top](#table-of-contents)** 353 | 354 | ### Avoid Side Effects (part 2) 355 | In JavaScript, primitives are passed by value and objects/arrays are passed by 356 | reference. In the case of objects and arrays, if your function makes a change 357 | in a shopping cart array, for example, by adding an item to purchase, 358 | then any other function that uses that `cart` array will be affected by this 359 | addition. That may be great, however it can be bad too. Let's imagine a bad 360 | situation: 361 | 362 | The user clicks the "Purchase", button which calls a `purchase` function that 363 | spawns a network request and sends the `cart` array to the server. Because 364 | of a bad network connection, the `purchase` function has to keep retrying the 365 | request. Now, what if in the meantime the user accidentally clicks "Add to Cart" 366 | button on an item they don't actually want before the network request begins? 367 | If that happens and the network request begins, then that purchase function 368 | will send the accidentally added item because it has a reference to a shopping 369 | cart array that the `addItemToCart` function modified by adding an unwanted 370 | item. 371 | 372 | A great solution would be for the `addItemToCart` to always clone the `cart`, 373 | edit it, and return the clone. This ensures that no other functions that are 374 | holding onto a reference of the shopping cart will be affected by any changes. 375 | 376 | Two caveats to mention to this approach: 377 | 1. There might be cases where you actually want to modify the input object, 378 | but when you adopt this programming practice you will find that those cases 379 | are pretty rare. Most things can be refactored to have no side effects! 380 | 381 | **Bad:** 382 | 383 | 384 | **Good:** 385 | 386 | 387 | **[⬆ back to top](#table-of-contents)** 388 | 389 | ### Don't write to global functions 390 | Polluting globals is a bad practice in JavaScript because you could clash with another 391 | library and the user of your API would be none-the-wiser until they get an 392 | exception in production. Let's think about an example: what if you wanted to 393 | extend JavaScript's native Array method to have a `diff` method that could 394 | show the difference between two arrays? You could write your new function 395 | to the `Array.prototype`, but it could clash with another library that tried 396 | to do the same thing. What if that other library was just using `diff` to find 397 | the difference between the first and last elements of an array? This is why it 398 | would be much better to just use ES2015/ES6 classes and simply extend the `Array` global. 399 | 400 | **Bad:** 401 | 402 | 403 | **Good:** 404 | 405 | **[⬆ back to top](#table-of-contents)** 406 | 407 | ### Favor functional programming over imperative programming 408 | JavaScript isn't a functional language in the way that Haskell is, but it has 409 | a functional flavor to it. Functional languages are cleaner and easier to test. 410 | Favor this style of programming when you can. 411 | 412 | **Bad:** 413 | 414 | 415 | **Good:** 416 | 417 | **[⬆ back to top](#table-of-contents)** 418 | 419 | ### Encapsulate conditionals 420 | 421 | **Bad:** 422 | 423 | 424 | **Good:** 425 | 426 | **[⬆ back to top](#table-of-contents)** 427 | 428 | ### Avoid negative conditionals 429 | 430 | **Bad:** 431 | 432 | 433 | **Good:** 434 | 435 | **[⬆ back to top](#table-of-contents)** 436 | 437 | ### Avoid conditionals 438 | This seems like an impossible task. Upon first hearing this, most people say, 439 | "how am I supposed to do anything without an `if` statement?" The answer is that 440 | you can use polymorphism to achieve the same task in many cases. The second 441 | question is usually, "well that's great but why would I want to do that?" The 442 | answer is a previous clean code concept we learned: a function should only do 443 | one thing. When you have classes and functions that have `if` statements, you 444 | are telling your user that your function does more than one thing. Remember, 445 | just do one thing. 446 | 447 | **Bad:** 448 | 449 | 450 | **Good:** 451 | 452 | **[⬆ back to top](#table-of-contents)** 453 | 454 | ### Don't over-optimize 455 | Modern browsers do a lot of optimization under-the-hood at runtime. A lot of 456 | times, if you are optimizing then you are just wasting your time. [There are good 457 | resources](https://github.com/petkaantonov/bluebird/wiki/Optimization-killers) 458 | for seeing where optimization is lacking. Target those in the meantime, until 459 | they are fixed if they can be. 460 | 461 | **Bad:** 462 | 463 | **Good:** 464 | 465 | **[⬆ back to top](#table-of-contents)** 466 | 467 | ### Remove dead code 468 | Dead code is just as bad as duplicate code. There's no reason to keep it in 469 | your codebase. If it's not being called, get rid of it! It will still be safe 470 | in your version history if you still need it. 471 | 472 | **Bad:** 473 | 474 | 475 | **Good:** 476 | 477 | **[⬆ back to top](#table-of-contents)** 478 | 479 | ## **Objects and Data Structures** 480 | ### Use getters and setters 481 | Using getters and setters to access data on objects could be better than simply 482 | looking for a property on an object. "Why?" you might ask. Well, here's an 483 | unorganized list of reasons why: 484 | 485 | * When you want to do more beyond getting an object property, you don't have 486 | to look up and change every accessor in your codebase. 487 | * Makes adding validation simple when doing a `set`. 488 | * Encapsulates the internal representation. 489 | * Easy to add logging and error handling when getting and setting. 490 | * You can lazy load your object's properties, let's say getting it from a 491 | server. 492 | 493 | 494 | **Bad:** 495 | 496 | 497 | **Good:** 498 | 499 | **[⬆ back to top](#table-of-contents)** 500 | 501 | 502 | ### Make objects have private members 503 | This can be accomplished through closures (for ES5 and below). 504 | 505 | **Bad:** 506 | 507 | 508 | **Good:** 509 | 510 | **[⬆ back to top](#table-of-contents)** 511 | 512 | ### Prefer composition over inheritance 513 | As stated famously in [*Design Patterns*](https://en.wikipedia.org/wiki/Design_Patterns) by the Gang of Four, 514 | you should prefer composition over inheritance where you can. There are lots of 515 | good reasons to use inheritance and lots of good reasons to use composition. 516 | The main point for this maxim is that if your mind instinctively goes for 517 | inheritance, try to think if composition could model your problem better. In some 518 | cases it can. 519 | 520 | You might be wondering then, "when should I use inheritance?" It 521 | depends on your problem at hand, but this is a decent list of when inheritance 522 | makes more sense than composition: 523 | 524 | 1. Your inheritance represents an "is-a" relationship and not a "has-a" 525 | relationship (Human->Animal vs. User->UserDetails). 526 | 2. You can reuse code from the base classes (Humans can move like all animals). 527 | 3. You want to make global changes to derived classes by changing a base class. 528 | (Change the caloric expenditure of all animals when they move). 529 | 530 | **Bad:** 531 | 532 | 533 | **Good:** 534 | 535 | **[⬆ back to top](#table-of-contents)** 536 | 537 | ## **SOLID** 538 | ### Single Responsibility Principle (SRP) 539 | As stated in Clean Code, "There should never be more than one reason for a class 540 | to change". It's tempting to jam-pack a class with a lot of functionality, like 541 | when you can only take one suitcase on your flight. The issue with this is 542 | that your class won't be conceptually cohesive and it will give it many reasons 543 | to change. Minimizing the amount of times you need to change a class is important. 544 | It's important because if too much functionality is in one class and you modify 545 | a piece of it, it can be difficult to understand how that will affect other 546 | dependent modules in your codebase. 547 | 548 | **Bad:** 549 | 550 | **Good:** 551 | 552 | **[⬆ back to top](#table-of-contents)** 553 | 554 | ### Open/Closed Principle (OCP) 555 | As stated by Bertrand Meyer, "software entities (classes, modules, functions, 556 | etc.) should be open for extension, but closed for modification." What does that 557 | mean though? This principle basically states that you should allow users to 558 | add new functionalities without changing existing code. 559 | 560 | **Bad:** 561 | 562 | 563 | **Good:** 564 | 565 | **[⬆ back to top](#table-of-contents)** 566 | 567 | ### Liskov Substitution Principle (LSP) 568 | This is a scary term for a very simple concept. It's formally defined as "If S 569 | is a subtype of T, then objects of type T may be replaced with objects of type S 570 | (i.e., objects of type S may substitute objects of type T) without altering any 571 | of the desirable properties of that program (correctness, task performed, 572 | etc.)." That's an even scarier definition. 573 | 574 | The best explanation for this is if you have a parent class and a child class, 575 | then the base class and child class can be used interchangeably without getting 576 | incorrect results. This might still be confusing, so let's take a look at the 577 | classic Square-Rectangle example. Mathematically, a square is a rectangle, but 578 | if you model it using the "is-a" relationship via inheritance, you quickly 579 | get into trouble. 580 | 581 | **Bad:** 582 | 583 | **Good:** 584 | 585 | **[⬆ back to top](#table-of-contents)** 586 | 587 | ### Interface Segregation Principle (ISP) 588 | JavaScript doesn't have interfaces so this principle doesn't apply as strictly 589 | as others. However, it's important and relevant even with JavaScript's lack of 590 | type system. 591 | 592 | ISP states that "Clients should not be forced to depend upon interfaces that 593 | they do not use." Interfaces are implicit contracts in JavaScript because of 594 | duck typing. 595 | 596 | A good example to look at that demonstrates this principle in JavaScript is for 597 | classes that require large settings objects. Not requiring clients to setup 598 | huge amounts of options is beneficial, because most of the time they won't need 599 | all of the settings. Making them optional helps prevent having a 600 | "fat interface". 601 | 602 | **Bad:** 603 | 604 | 605 | **Good:** 606 | 607 | **[⬆ back to top](#table-of-contents)** 608 | 609 | ### Dependency Inversion Principle (DIP) 610 | This principle states two essential things: 611 | 1. High-level modules should not depend on low-level modules. Both should 612 | depend on abstractions. 613 | 2. Abstractions should not depend upon details. Details should depend on 614 | abstractions. 615 | 616 | This can be hard to understand at first, but if you've worked with AngularJS, 617 | you've seen an implementation of this principle in the form of Dependency 618 | Injection (DI). While they are not identical concepts, DIP keeps high-level 619 | modules from knowing the details of its low-level modules and setting them up. 620 | It can accomplish this through DI. A huge benefit of this is that it reduces 621 | the coupling between modules. Coupling is a very bad development pattern because 622 | it makes your code hard to refactor. 623 | 624 | As stated previously, JavaScript doesn't have interfaces so the abstractions 625 | that are depended upon are implicit contracts. That is to say, the methods 626 | and properties that an object/class exposes to another object/class. In the 627 | example below, the implicit contract is that any Request module for an 628 | `InventoryTracker` will have a `requestItems` method. 629 | 630 | **Bad:** 631 | 632 | 633 | **Good:** 634 | 635 | **[⬆ back to top](#table-of-contents)** 636 | 637 | ## **Testing** 638 | Testing is more important than shipping. If you have no tests or an 639 | inadequate amount, then every time you ship code you won't be sure that you 640 | didn't break anything. Deciding on what constitutes an adequate amount is up 641 | to your team, but having 100% coverage (all statements and branches) is how 642 | you achieve very high confidence and developer peace of mind. This means that 643 | in addition to having a great testing framework, you also need to use a 644 | [good coverage tool](http://gotwarlost.github.io/istanbul/). 645 | 646 | There's no excuse to not write tests. There's plenty of good test frameworks, so find one that your team prefers. 647 | When you find one that works for your team, then aim to always write tests 648 | for every new feature/module you introduce. If your preferred method is 649 | Test Driven Development (TDD), that is great, but the main point is to just 650 | make sure you are reaching your coverage goals before launching any feature, 651 | or refactoring an existing one. 652 | 653 | ### Single concept per test 654 | 655 | **Bad:** 656 | 657 | **Good:** 658 | 659 | **[⬆ back to top](#table-of-contents)** 660 | 661 | ## **Error Handling** 662 | Thrown errors are a good thing! They mean the runtime has successfully 663 | identified when something in your program has gone wrong and it's letting 664 | you know by stopping function execution on the current stack, killing the 665 | process (in Node), and notifying you in the console with a stack trace. 666 | 667 | ### Don't ignore caught errors 668 | Doing nothing with a caught error doesn't give you the ability to ever fix 669 | or react to said error. Logging the error to the console (`console.log`) 670 | isn't much better as often times it can get lost in a sea of things printed 671 | to the console. If you wrap any bit of code in a `try/catch` it means you 672 | think an error may occur there and therefore you should have a plan, 673 | or create a code path, for when it occurs. 674 | 675 | **Bad:** 676 | 677 | **Good:** 678 | 679 | **[⬆ back to top](#table-of-contents)** 680 | 681 | ## **Formatting** 682 | Formatting is subjective. Like many rules herein, there is no hard and fast 683 | rule that you must follow. The main point is DO NOT ARGUE over formatting. 684 | There are tons of tools to automate this. 685 | Use one! It's a waste of time and money for engineers to argue over formatting. 686 | 687 | For things that don't fall under the purview of automatic formatting 688 | (indentation, tabs vs. spaces, double vs. single quotes, etc.) look here 689 | for some guidance. 690 | 691 | ### Use consistent capitalization 692 | JavaScript is untyped, so capitalization tells you a lot about your variables, 693 | functions, etc. These rules are subjective, so your team can choose whatever 694 | they want. The point is, no matter what you all choose, just be consistent. 695 | 696 | **Bad:** 697 | 698 | **Good:** 699 | 700 | **[⬆ back to top](#table-of-contents)** 701 | 702 | 703 | ### Function callers and callees should be close 704 | If a function calls another, keep those functions vertically close in the source 705 | file. Ideally, keep the caller right above the callee. We tend to read code from 706 | top-to-bottom, like a newspaper. Because of this, make your code read that way. 707 | 708 | **Bad:** 709 | 710 | **Good:** 711 | 712 | **[⬆ back to top](#table-of-contents)** 713 | 714 | ## **Comments** 715 | ### Only comment things that have business logic complexity. 716 | Comments are an apology, not a requirement. Good code *mostly* documents itself. 717 | 718 | **Bad:** 719 | ```java 720 | // Creating a List of customer names 721 | List customerNames = Arrays.asList('Bob', 'Linda', 'Steve', 'Mary'); 722 | 723 | // Using Stream findFirst() 724 | Optional firstCustomer = customerNames.stream().findFirst(); 725 | 726 | // if the stream is empty, an empty 727 | // Optional is returned. 728 | if (firstCustomer.isPresent()) { 729 | System.out.println(firstCustomer.get()); 730 | } 731 | else { 732 | System.out.println("no value"); 733 | } 734 | ``` 735 | 736 | 737 | **Good:** 738 | ```java 739 | List customerNames = Arrays.asList('Bob', 'Linda', 'Steve', 'Mary'); 740 | 741 | Optional firstCustomer = customerNames.stream().findFirst(); 742 | 743 | if (firstCustomer.isPresent()) { 744 | System.out.println(firstCustomer.get()); 745 | } 746 | else { 747 | System.out.println("no value"); 748 | } 749 | ``` 750 | 751 | **[⬆ back to top](#table-of-contents)** 752 | 753 | ### Don't Use a Comment When You Can Use a Function or a Variable 754 | The best comment is no comment 755 | 756 | **Bad:** 757 | ```java 758 | //Check to see if order is eligible to ship 759 | if((order.isPaid & order.isLabeled) && CUSTOMER_FLAG) { 760 | // ... 761 | } 762 | ``` 763 | 764 | 765 | **Good:** 766 | ```java 767 | if(order.isEligibleToShip()) { 768 | // ... 769 | } 770 | ``` 771 | 772 | **[⬆ back to top](#table-of-contents)** 773 | 774 | ### Don't leave commented out code in your codebase 775 | Version control exists for a reason. Leave old code in your history. 776 | 777 | **Bad:** 778 | ```java 779 | doStuff(); 780 | // doOtherStuff(); 781 | // doSomeMoreStuff(); 782 | // doSoMuchStuff(); 783 | ``` 784 | 785 | 786 | **Good:** 787 | ```java 788 | doStuff(); 789 | ``` 790 | 791 | **[⬆ back to top](#table-of-contents)** 792 | 793 | ### Don't have journal comments 794 | Remember, use version control! There's no need for dead code, commented code, 795 | and especially journal comments. Use `git log` to get history! 796 | 797 | **Bad:** 798 | ```java 799 | /** 800 | * 2021-03-06: Renamed clean to cleanCode (DL) 801 | * 2020-01-03: Changed return value (LB) 802 | * 2019-05-12: Added clean method (DL) 803 | */ 804 | cleanCode(String code) { 805 | return null; 806 | } 807 | ``` 808 | 809 | **Good:** 810 | ```java 811 | cleanCode(String code) { 812 | return null; 813 | } 814 | ``` 815 | 816 | **[⬆ back to top](#table-of-contents)** 817 | 818 | ### Avoid positional markers 819 | They usually just add noise. Let the functions and variable names along with the 820 | proper indentation and formatting give the visual structure to your code. 821 | 822 | **Bad:** 823 | ```java 824 | //////////////////////////////////////////////////////////////////////////////// 825 | // Instantiate Order List 826 | //////////////////////////////////////////////////////////////////////////////// 827 | List orders = new ArrayList(); 828 | 829 | //////////////////////////////////////////////////////////////////////////////// 830 | // Ship Orders that are eligible 831 | //////////////////////////////////////////////////////////////////////////////// 832 | 833 | orders.filter(Order::isEligibleToShip).forEach(x -> ship(x)); 834 | ``` 835 | 836 | **Good:** 837 | ```java 838 | List orders = new ArrayList(); 839 | 840 | orders.filter(Order::isEligibleToShip).forEach(x -> ship(x)); 841 | ``` 842 | 843 | **[⬆ back to top](#table-of-contents)** 844 | 845 | ## Translation 846 | 847 | Open for translations. 848 | 849 | **[⬆ back to top](#table-of-contents)** 850 | --------------------------------------------------------------------------------