„Clean Code Explained“ - praktinis įvadas į švarų kodavimą pradedantiesiems

„Bet kuris kvailys gali rašyti kodas, kurį gali suprasti kompiuteris. Geri programuotojai rašo kodą, kurį žmonės gali suprasti. "- Martinas Fowleris

Rašyti švarų, suprantamą ir prižiūrimą kodą yra įgūdis, kurį labai svarbu įsisavinti kiekvienam kūrėjui.

Šiame įraše mes apžvelgsime svarbiausius principus, kaip pagerinti kodo kokybę, ir pateiksiu kiekvieno iš jų kodų pavyzdžius.

Dauguma pavyzdžių yra iš Roberto J. Martino „ Švaraus kodekso“ . Tai programavimo klasika ir aš siūlau jums perskaityti visą tekstą, kai turite laiko.

Kaip pavadinti kintamuosius (ir kitus dalykus)

"Kompiuterijoje yra tik du sunkūs dalykai: talpyklos pripažinimas negaliojančia ir daiktų įvardijimas." - Philas Karltonas

Yra priežastis, kodėl nenaudojame atminties adresų, o vietoj jų turime pavadinimus: vardus daug lengviau prisiminti. Dar svarbiau, kad jie gali suteikti jums daugiau informacijos apie kintamąjį, kad kažkas kitas galėtų suprasti jo reikšmę.

Gali praeiti šiek tiek laiko surasti gerą vardą, tačiau tai sutaupys jums ir jūsų komandai dar daugiau laiko ateityje. Aš esu įsitikinęs, kad dauguma skaitytojų susidūrė su situacija, kai aplankei savo kodą tik po kelių mėnesių ir sunkiai supranti, ką padarei anksčiau.

Kaip sukurti prasmingus vardus

Nenaudokite komentarų, kad paaiškintumėte, kodėl naudojamas kintamasis. Jei vardui reikia komentaro, turėtumėte skirti laiko kintamojo pervadinimui, o ne komentaro rašymui.

"Pavadinimas turėtų jums pasakyti, kodėl jis egzistuoja, ką jis veikia ir kaip jis naudojamas. Jei vardui reikia komentaro, vardas neatskleidžia jo ketinimo." - Švarus kodas

Blogas:

var d; // elapsed time in days

Aš mačiau tokio tipo kodus tiek kartų. Paplitusi klaidinga nuomonė, kad turėtumėte slėpti savo netvarką komentarais. Nenaudokite raidžių, tokių kaip x, y, a ar b, kaip kintamųjų pavadinimų, nebent yra rimta priežastis (ciklo kintamieji yra šios išimtis).

Gerai:

var elapsedTimeInDays; var daysSinceCreation; var daysSinceModification;

Šie vardai yra daug geresni. Jie pasako, kas yra matuojama, ir to matavimo vienetą.

Venkite dezinformacijos

Būkite atsargūs dėl žodžių, kurie reiškia kažką konkretaus. Nenurodykite sąskaitų grupavimo kaip „ accountList“, nebent jos tipas iš tikrųjų yra sąrašas. Žodis turi specifinę reikšmę ir gali padaryti klaidingas išvadas.

Net jei tipas yra sąrašas, paskyros yra paprastesnis ir geresnis pavadinimas.

Blogas:

var accountList = [];

Gerai:

var accounts = []

Venkite triukšmo žodžių

Triukšmo žodžiai yra žodžiai, kurie nepateikia jokios papildomos informacijos apie kintamąjį. Jie yra nereikalingi ir turėtų būti pašalinti.

Kai kurie populiarūs triukšmo žodžiai yra šie:

  • (Priešdėlis)
  • Informacija
  • Duomenys
  • Kintamas
  • Objektas
  • Vadybininkas

Jei jūsų klasė pavadinta „UserInfo“, galite tiesiog pašalinti informaciją ir padaryti ją naudotoja. Naudojant „BookData“, o ne „Book“ kaip klasės pavadinimą, tiesiog nereikia vargti, nes klasė vis tiek saugo duomenis.

Čia taip pat galite perskaityti Jeffo Atwoodo tinklaraščio įrašą apie „SomethingManager“ vardus.

Naudokite tariamus vardus

Jei negalite ištarti vardo, negalite jo aptarti, neskambėdamas kvailai.

Blogas:

const yyyymmdstr = moment().format("YYYY/MM/DD"); 

Gerai:

const currentDate = moment().format("YYYY/MM/DD");

Naudokite ieškomus vardus

Venkite savo kode naudoti stebuklingus skaičius. Pasirinkite ieškomas, pavadintas konstantas. Nenaudokite pavienių raidžių konstantoms, nes jos gali pasirodyti daugelyje vietų, todėl jų nėra lengva ieškoti.

Blogas:

if (student.classes.length < 7) { // Do something }

Gerai:

if (student.classes.length < MAX_CLASSES_PER_STUDENT) { // Do something }

Tai yra daug geriau, nes MAX_CLASSES_PER_STUDENT galima naudoti daugelyje kodo vietų. Jei ateityje jį reikės pakeisti į 6, galime tiesiog pakeisti konstantą.

Blogas pavyzdys sukuria klaustukus skaitytojo galvoje, pavyzdžiui, kokia yra 7 reikšmė?

Taip pat turėtumėte pasinaudoti savo kalbos nuolatiniais pavadinimų ir deklaravimo būdais, pvz., „Java“ asmeniniu statiniu galutiniu arba „JavaScript“ „ const “.

Būkite nuoseklūs

Laikykitės vieno žodžio kiekvienai sąvokai . Nenaudokite gauti , gauti ir gauti tą pačią operaciją skirtingose ​​klasėse. Pasirinkite vieną iš jų ir naudokite jį visame projekte, kad žmonės, prižiūrintys kodo bazę, arba jūsų API klientai galėtų lengvai rasti ieškomus metodus.

Kaip rašyti funkcijas

Laikykite juos mažus

Funkcijos turėtų būti mažos, tikrai mažos. Jie retai turėtų būti 20 eilučių. Kuo ilgesnė funkcija, tuo labiau tikėtina, kad ji daro kelis dalykus ir turi šalutinį poveikį.

Įsitikinkite, kad jie tiesiog daro vieną dalyką

Funkcijos turėtų atlikti vieną dalyką. Jie turėtų tai padaryti gerai. Jie turėtų tai daryti tik. - Švarus kodas

Your functions should do only one thing. If you follow this rule, it is guaranteed that they will be small. The only thing that function does should be stated in its name.

Sometimes it is hard to look at the function and see if it is doing multiple things or not. One good way to check is to try to extract another function with a different name. If you can find it, that means it should be a different function.

This is probably the most important concept in this article, and it will take some time to get used to. But once you get the hang of it, your code will look much more mature, and it will be more easily refactorable, understandable, and testable for sure.

Encapsulate Conditionals in Functions

Refactoring the condition and putting it into a named function is a good way to make your conditionals more readable.

Here is a piece of code from a school project of mine. This code is responsible for inserting a chip on the board of the Connect4 game.

The isValidInsertion method takes care of checking the validity of the column number and allows us the focus on the logic for inserting the chip instead.

public void insertChipAt(int column) throws Exception { if (isValidInsertion(column)) { insertChip(column); boardConfiguration += column; currentPlayer = currentPlayer == Chip.RED ? Chip.YELLOW : Chip.RED; } else  if (!columnExistsAt(column)) throw new IllegalArgumentException(); else if (isColumnFull(column - 1)  }

Here is the code for isValidInsertion, if you are interested.

 private boolean isValidInsertion(int column) { boolean columnIsAvailable = column = 1 && numberOfItemsInColumn[column - 1] < NUM_ROWS; boolean gameIsOver = getWinner() != Chip.NONE; return columnIsAvailable && !gameIsOver; } 

Without the method, if condition would look like this:

if (column = 1 && numberOfItemsInColumn[column - 1] < NUM_ROWS && getWinner() != Chip.NONE)

Gross, right? I agree.

Fewer Arguments

Functions should have two or fewer arguments, the fewer the better. Avoid three or more arguments where possible.

Arguments make it harder to read and understand the function. They are even harder from a testing point of view, since they create the need to write test cases for every combination of arguments.

Do not use Flag Arguments

A flag argument is a boolean argument that is passed to a function. Two different actions are taken depending on the value of this argument.

For example, say there is a function that is responsible for booking tickets to a concert and there are 2 types of users: Premium and Regular. You can have code like this:

 public Booking book (Customer aCustomer, boolean isPremium) { if(isPremium) // logic for premium book else // logic for regular booking }

Flag arguments naturally contradict the principle of single responsibility. When you see them, you should consider dividing the function into two.

Do Not Have Side Effects

Side effects are unintended consequences of your code. They may be changing the passed parameters, in case of passing by reference, or maybe changing a global variable.

The key point is, they promised to do another thing and you need to read the code carefully to notice the side-effect. They can result in some nasty bugs.

Here is an example from the book:

public class UserValidator { private Cryptographer cryptographer; public boolean checkPassword(String userName, String password) { User user = UserGateway.findByName(userName); if (user != User.NULL) { String codedPhrase = user.getPhraseEncodedByPassword(); String phrase = cryptographer.decrypt(codedPhrase, password); if ("Valid Password".equals(phrase)) { Session.initialize(); return true; } } return false; } }

Can you see the side-effect of this function?

It is checking the password, but when the password is valid, it is also initializing the session which is a side-effect.

You can change the name of the function to something like checkPasswordAndInitializeSession to make this effect explicit. But when you do that, you should notice that your function is actually doing two things and you should not initialize the session here.

Don't Repeat Yourself

Code repetition may be the root of all evil in software. Duplicate code means you need to change things in multiple places when there is a change in logic and it is very error prone.

Use your IDE's refactoring features and extract a method whenever you come across a repeated code segment.

Bonus

Do not leave code in comments

Please, do not. This one is serious because others who see the code will be afraid to delete it because they do not know if it is there for a reason. That commented out code will stay there for a long time. Then when variable names or method names change, it gets irrelevant but still nobody deletes it.

Just delete it. Even if it was important, there is version control for that. You can always find it.

Know your language's conventions

You should know your language's conventions in terms of spacing, comments, and naming things. There are style guides available for many languages.

For example, you should use camelCase in Java but snake_case in Python. You put opening braces on a new line in C# but you put them on the same line in Java and JavaScript.

These things change from language to language and there is no universal standard.

Štai keletas jums naudingų nuorodų:

  • „Python“ stiliaus vadovas
  • „Google“ stiliaus vadovas „Javascript“
  • „Google Java“ stiliaus vadovas

Išvada

Švarus kodavimas nėra įgūdis, kurį galima įgyti per naktį. Tai įprotis, kurį reikia išsiugdyti, turint omenyje šiuos principus ir taikant juos kiekvieną kartą, kai rašote kodą.

Ačiū, kad skyrėte laiko skaityti, ir tikiuosi, kad tai buvo naudinga.

Jei jus domina skaityti daugiau tokių straipsnių, galite užsiprenumeruoti mano tinklaraštį.