

Korrekte navne
Korrekte navne forbedrer kodelæsbarheden og reducerer dermed den tid, det tager at sætte sig ind i koden, fordi det er meget nemmere at bruge en metode, når dens navn groft beskriver dens funktionalitet. Alt i kode består af navne (variabler, metoder, klasser, objekter, filer osv.), så dette punkt bliver meget vigtigt, når man laver korrekt, ren kode. Baseret på ovenstående skal navnet formidle betydning, for eksempel hvorfor variablen eksisterer, hvad den gør, og hvordan den bruges. Jeg vil bemærke mere end én gang, at den bedste kommentar til en variabel er at give den et godt navn.
fra tv-serien "Sherlock" (2010-2017)
Navngivning af grænseflader
Grænseflader har normalt navne, der starter med et stort bogstav og er skrevet i CamelCase. Når man skrev en grænseflade, blev det tidligere betragtet som god praksis at tilføje præfikset "I" for at udpege det som en grænseflade (for eksempel IUserService), men det ser ret grimt og distraherende ud. I sådanne tilfælde er det bedre at udelade præfikset (UserService) og tilføje "Impl" som et suffiks til navnet på dets implementering (f.eks. UserServiceImpl). Eller eventuelt, som en sidste udvej, tilføje et "C" præfiks til navnet på implementeringen (f.eks. CUserService).Klassenavne
Ligesom grænseflader skrives klassenavne med stort og bruger CamelCase. Det er lige meget, om vi står over for en zombieapokalypse, det er lige meget, om slutningen er nær - aldrig, aldrig, aldrig bør navnet på en klasse være et verbum! Klasse- og objektnavne skal være navneord eller sammensatte navneord (UserController, UserDetails, UserAccount, og så videre). Du bør ikke sætte forkortelsen af applikationen ind i slutningen af navnet på hver klasse, da det kun ville tilføje unødvendig kompleksitet. For eksempel, hvis vi har en User Data Migration-applikation, så lad være med at tilføje "UDM" til hver klasse, dvs. UDMUserDetails, UDMUserAccount, UDMUserController.Metodenavne
Normalt begynder metodenavne med et lille bogstav, men de bruger også kamel-case-stil (camelCase). Ovenfor sagde vi, at klassenavne aldrig må være verber. Her er situationen lige omvendt: navnene på metoderne skal være verber eller verbum: findUserById, findAllUsers, createUser, og så videre. Når du opretter en metode (såvel som variabler og klasser), så brug en konsekvent navnekonvention for at undgå forvirring. For at finde en bruger kan en metode f.eks. hedde getUserById eller findUserById. Og en ting mere: Brug ikke humor i navnene på metoderne, for andre forstår måske ikke vittigheden. Som følge heraf kan de ikke forstå, hvad metoden gør.Variable navne
I de fleste tilfælde begynder variabelnavne med et lille bogstav og bruger også camelCase, undtagen når variablen er en global konstant. I sådanne tilfælde skrives alle bogstaver i navnet med store bogstaver, og ordene er adskilt af en understregning ("_"). For nemheds skyld kan du bruge meningsfuld kontekst, når du navngiver variabler. Med andre ord, når en variabel eksisterer som en del af noget større, for eksempel fornavn, efternavn eller status. I sådanne tilfælde kan du tilføje et præfiks, der angiver det objekt, som denne variabel tilhører. For eksempel: userFirstName, userLastName, userStatus. Du bør også undgå lignende navne for variabler, når de har helt forskellige betydninger. Her er nogle hyppigt forekommende antonymer, der bruges i variabelnavne:- begynde/slut
- først sidst
- låst/låst op
- min/max
- næste/forrige
- gammel/ny
- åbnet/lukket
- synlig/usynlig
- kilde/mål
- kilde/destination
- op ned
Korte variabelnavne
Når vi har variabler som x eller n eller sådan noget, ser vi ikke umiddelbart hensigten med den person, der skrev koden. Det er ikke indlysende, hvad n gør. At finde ud af det kræver mere omhyggelig kontemplation (og det betyder tid, tid, tid). Antag for eksempel, at vi har et felt, der repræsenterer id'et for den ansvarlige bruger. I stedet for et variabelnavn som x eller blot id, vil vi navngive denne variabel "responsibleUserId", som straks forbedrer læsbarheden og informationsindholdet. Når det er sagt, har korte navne som n en plads som lokale variabler i små metoder, hvor kodeblokken, der involverer denne variabel, kun er et par linjer lang, og metodenavnet beskriver perfekt, hvad der sker der. Når en udvikler ser en sådan variabel, forstår den, at den er af sekundær betydning og har et meget begrænset omfang. Som et resultat heraf har omfanget en vis afhængighed af et variabelnavns længde: Jo længere navnet er, jo mere globalt er variablen og omvendt. Som et eksempel er her en metode til at finde den sidst gemte bruger efter dato:
public User findLastUser() {
return findAllUsers().stream()
.sorted((x, y) -> -x.getCreatedDate().compareTo(y.getCreatedDate()))
.findFirst()
.orElseThrow(() -> new ResourceNotFoundException("No user exists"));
}
Her bruger vi kortnavnede variable x og y til at sortere strømmen, og så glemmer vi dem.
Optimal længde
Lad os fortsætte med emnet navnelængde. Den optimale navnelængde er et sted mellem n og maximumNumberOfUsersInTheCurrentGroup. Korte navne lider med andre ord under manglende betydning, mens navne, der er for lange, forlænger programmet uden at tilføje læsbarhed, og vi er simpelthen for dovne til at skrive dem hver gang. Bortset fra tilfældet beskrevet ovenfor for variabler med et kort navn som n, bør du holde dig til en længde på omkring 8-16 tegn. Dette er ikke en streng regel, kun en retningslinje.Små forskelle
Jeg kan ikke undlade at nævne subtile forskelle i navne. Dette er også en dårlig praksis, da disse forskelle simpelthen kan være forvirrende eller kræve at bruge meget ekstra tid på at lægge mærke til dem. For eksempel er forskellen mellem InvalidDataAccessApiUsageException og InvalidDataAccessResourceUsageException svær at få øje på med et øjeblik. Der kan også ofte opstå forvirring ved brug af små bogstaver L og O, fordi de let kan forveksles med 1 og 0. I nogle skrifttyper er forskellen mere tydelig, i nogle er den mindre.Betydningen
Vi skal gøre navne meningsfulde, men ikke skabe tvetydighed gennem synonymer, da for eksempel UserData og UserInfo faktisk har samme betydning. I dette tilfælde skal vi grave dybere ned i koden for at forstå, hvilket bestemt objekt vi har brug for. Undgå ord, der ikke formidler nyttig information. For eksempel, i firstNameString, hvorfor har vi brug for ordet String? Kan dette virkelig være et Dato-objekt? Selvfølgelig ikke. Så vi bruger simpelthen fornavn. Jeg vil også gerne nævne booleske variable. Som et eksempel, tag en boolsk navngivet flagDeleted. Ordet flag har ingen betydning. Det er mere rimeligt at kalde det er slettet.Desinformation
Jeg vil også gerne sige et par ord om forkerte navnekonventioner. Lad os sige, at vi har en variabel ved navn userActivityList, men i stedet for at være en liste, er dette objekt en anden containertype eller brugerdefineret lagerobjekt. Dette kunne forvirre den gennemsnitlige programmør: det er bedre at kalde det noget som userActivityGroup eller userActivities.Søg
En af ulemperne ved korte og enkle navne er, at de er svære at finde i en stor kode – hvad ville være nemmere at finde: "navn" eller "NAME_FOR_DEFAULT_USER"? Den anden mulighed, selvfølgelig. Vi bør undgå ofte stødte på ord (bogstaver) i navne, da de kun vil øge antallet af matchende filer under en søgning, hvilket ikke er godt. Jeg vil gerne minde dig om, at programmører bruger mere tid på at læse kode end at skrive den, så vær smart med at navngive elementerne i din applikation. Men hvad nu hvis et godt navn bare ikke kan findes? Hvad hvis navnet på en metode ikke beskriver dens funktionalitet godt? Det er her, kommentarer kommer på scenen.Kommentarer

Typer af kommentarer
-
Juridiske kommentarer — Kommentarer i begyndelsen af hver kildefil af juridiske årsager, for eksempel:
* Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved. * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
-
Informative kommentarer — Kommentarer, der repræsenterer en forklaring af koden (der giver yderligere oplysninger eller forklarer hensigten med en given kodesektion).
For eksempel:
/* * Combines the user from the database with the one passed for updating * When a field in requestUser is empty, it is filled with old data from foundUser */ private User mergeUser(User requestUser, User foundUser) { return new User( foundUser.getId(), requestUser.getFirstName() == null ? requestUser.getFirstName() : foundUser.getFirstName(), requestUser.getMiddleName() == null ? requestUser.getMiddleName() : foundUser.getMiddleName(), requestUser.getLastName() == null ? requestUser.getLastName() : foundUser.getLastName(), requestUser.getAge() == null ? requestUser.getAge() : foundUser.getAge() ); }
I dette tilfælde kan du undvære kommentarer, da navnet på metoden og dens parametre kombineret med meget gennemsigtig funktionalitet beskriver sig selv godt.
-
Advarselskommentarer — Kommentar beregnet til at advare andre udviklere om de uønskede konsekvenser af en handling (for eksempel at advare dem om, hvorfor en test blev markeret som @Ignorer):
// Takes too long to run // Don't run if you don't have a lot of time @Ignore @Test public void someIntegrationTest() { …… }
-
TODO — Kommentarer, der er en note om noget, der skal gøres i fremtiden, men som af en eller anden grund ikke kan gøres nu. Dette er en god praksis, men sådanne kommentarer bør gennemgås regelmæssigt for at fjerne irrelevante og undgå rod.
Et eksempel ville være:
// TODO: Add a check for the current user ID (when the security context is created) @Override public Resource downloadFile(File file) { return fileManager.download(file); }
Her bemærker vi det faktum, at vi skal tilføje en sammenligning af brugeren, der udfører download-handlingen (hvis ID vi vil udtrække fra sikkerhedskonteksten) med den, der udførte lagringsoperationen.
-
Forstærkende kommentarer — Kommentarer, der understreger vigtigheden af en omstændighed, der ved første øjekast kan virke ubetydelig.
Som et eksempel kan du overveje et stykke af en metode, der fylder en testdatabase med nogle scripts:
Stream.of(IOUtils.resourceToString("/fill-scripts/" + x, StandardCharsets.UTF_8) .trim() .split(";")) .forEach(jdbcTemplate::update); // The trim() call is very important. It removes possible spaces at the end of the script // so that when we read and split into separate requests, we don't end up with empty ones
-
Javadoc-kommentarer — Kommentarer, der beskriver API'et for visse funktioner. Der er nok de mest nyttige kommentarer, da den dokumenterede API er meget nemmere at arbejde med. Når det er sagt, kan de også være forældede som enhver anden type kommentar. Så glem aldrig, at hovedbidraget til dokumentation ikke kommer af kommentarer, men af god kode.
Her er et eksempel på en ret almindelig metode til at opdatere en bruger:
/** * Updates the passed fields for a user based on its id. * * @param id id of the user to be updated * @param user user with populated fields for updating * @return updated user */ User update(Long id, User user);
Dårlige kommentarer
-
mumlende kommentar — Kommentarer, der normalt skrives i en fart, og hvis betydning kun er forståelig for udvikleren, der har skrevet dem, da kun han eller hun opfatter den nuancerede situation, som kommentaren refererer til.
Overvej dette eksempel:
public void configureSomeSystem() { try{ String configPath = filesLocation.concat("/").concat(CONFIGURATION_FILE); FileInputStream stream = new FileInputStream(configPath); } catch (FileNotFoundException e) { // If there is no configuration file, the default configuration is loaded } }
Hvem indlæser disse indstillinger? Er de allerede blevet indlæst? Skal denne metode fange undtagelser og indlæse standardindstillinger? Der opstår for mange spørgsmål, som kun kan besvares ved at dykke ned i en undersøgelse af andre dele af systemet.
- Redundante kommentarer — Kommentarer, der ikke bærer nogen semantisk belastning, da det, der sker i en given sektion af koden, er helt klart. Kommentaren er med andre ord ikke nemmere at læse end koden.
Lad os se et eksempel:
public class JdbcConnection{ public class JdbcConnection{ /** * The logger associated with the current class */ private Logger log = Logger.getLogger(JdbcConnection.class.getName()); /** * Creates and returns a connection using the input parameters */ public static Connection buildConnection(String url, String login, String password, String driver) throws Exception { Class.forName(driver); connection = DriverManager.getConnection(url, login, password); log.info("Created connection with db"); return connection; }
Hvad er meningen med sådanne kommentarer? Alt, hvad de forklarer, er allerede helt klart.
-
Upålidelige kommentarer — Kommentarer, der er usande og kun vildledende (desinformation). For eksempel, her er en.
/** * Helper method. Closes the connection with the scanner if isNotUsing is true */ private void scanClose(Scanner scan, boolean isNotUsing) throws Exception { if (!isNotUsing) { throw new Exception("The scanner is still in use"); } scan.close(); }
Hvad er der galt med denne kommentar? At det lyver lidt for os, i og med at forbindelsen lukkes hvis isNotUsing er falsk, ikke omvendt, som kommentaren oplyser os om.
-
Obligatoriske kommentarer — Kommentarer, der anses for obligatoriske (f.eks. Javadoc-kommentarer), men som faktisk nogle gange hober sig for meget op og er upålidelige og unødvendige (du skal tænke over, om disse kommentarer faktisk er nødvendige).
Eksempel:
/**
* Create a user based on the parameters
* @param firstName first name of the created user
* @param middleName middle name of the created user
* @param lastName last name of the created user
* @param age age of the created user
* @param address address of the created user
* @return user that was created
*/
User createNewUser(String firstName, String middleName, String lastName, String age, String address);
Ville du være i stand til at forstå, hvad metoden gør uden disse kommentarer? Mest sandsynligt, ja, så kommentarer bliver meningsløse her.
Logkommentarer — Kommentarer, der nogle gange føjes til begyndelsen af et modul, hver gang det redigeres (noget som en ændringslog).
/**
* Records kept since January 9, 2020;
**********************************************************************
* 9 Jan 2020: Providing a database connection using JDBC Connection;
* 15 Jan 2020: Adding DAO-level interfaces for working with the database;
* 23 Jan 2020: Adding integration tests for the database;
* 28 Jan 2020: Implementation of DAO-level interfaces;
* 1 Feb 2020: Development of interfaces for services,
* in accordance with the requirements specified in user stories;
* 16 Feb 2020: Implementation of service interfaces
* (implementation of business logic related to the work of the database);
* 25 Feb 2020: Adding tests for services;
* 8 Mar 2020: Celebration of International Women's Day (Terry is drunk again);
* 21 Mar 2020: Refactoring the service layer;
*/
Denne tilgang var engang berettiget, men med fremkomsten af versionskontrolsystemer (for eksempel Git) blev det en unødvendig rod og komplikation af koden.
Forfatterskabskommentarer — Kommentarer, hvis formål er at angive den person, der har skrevet koden, så du kan kontakte ham/hende og diskutere hvordan, hvad og hvorfor, f.eks.
* @author Bender Bending
Endnu en gang husker versionskontrolsystemer nøjagtigt, hvem der tilføjede enhver kode og hvornår, så denne tilgang er overflødig.
Udkommen kode — Kode, der blev kommenteret ud af en eller anden grund. Dette er en af de værste vaner, for det, der sker, er, at du kommenterer noget og glemmer det, og så har andre udviklere bare ikke modet til at slette det (trods alt, hvad nu hvis det er noget værdifuldt?).
// public void someMethod(SomeObject obj) {
// .....
// }
Som et resultat akkumuleres kommenteret kode som skrald. I intet tilfælde bør du efterlade en sådan kode. Hvis du virkelig har brug for det, så glem ikke versionskontrolsystemet.
Ikke-oplagte kommentarer — Kommentarer, der beskriver noget på en alt for kompliceret måde.
/*
* Start with an array large enough to store
* all the data bytes (plus filter bytes) with a cushion, plus 300 bytes
* for header data
*/
this.dataBytes = new byte[(this.size * (this.deep + 1) * 2)+300];
En kommentar skal forklare koden. Det burde ikke i sig selv kræve en forklaring. Så hvad er der galt her? Hvad er "filterbytes"? Hvad handler det "+1" om? Hvorfor lige præcis 300?
- Brug stilarter, der er nemme at vedligeholde: At vedligeholde stilarter, der er for fancy og eksotiske, er irriterende og tidskrævende.
- Brug ikke end-of-line kommentarer, der refererer til enkelte linjer: Resultatet er en stor bunke kommentarer. Hvad mere er, er det svært at finde en meningsfuld kommentar for hver linje.
- Når du skriver en kommentar, så prøv at besvare spørgsmålet "hvorfor", ikke "hvordan".
- Undgå forkortet information. Som jeg sagde ovenfor, behøver vi ikke en forklaring på en kommentar: selve kommentaren er forklaringen.
- Du kan bruge kommentarer til at notere enheder og værdiintervaller.
- Placer kommentarer tæt på den kode, de beskriver.
GO TO FULL VERSION