Uw code kan ruiken! Hoe repareer je het

Uw code kan ruiken! Hoe repareer je het / Programming

EEN code geur is een stuk code of algemeen coderingspatroon dat lijkt op een diepere kwestie in de algemene structuur en het ontwerp van een codebase.

Beschouw een code geur als een teken dat suggereert dat een deel van de code moet worden refactored. Het is niet dat de code buggy of niet-functioneel is - vaak werkt stinkende code prima - maar stinkende code is vaak moeilijk te onderhouden en uit te breiden, wat kan leiden tot technische problemen (vooral bij grotere projecten).

In dit artikel belichten we 10 van de meest voorkomende codengeuren, waar je op moet letten en hoe je ze kunt ontgeuren. Als je een nieuwe programmeur bent Hoe leer je programmeren zonder al de stress Leren programmeren zonder al je stress Misschien heb je besloten om te blijven programmeren, of het nu voor een carrière is of gewoon als een hobby. Super goed! Maar misschien begin je je overweldigd te voelen. Niet zo goed. Hier is hulp om uw reis te vergemakkelijken. Lees Meer, vermijd deze en uw code zal merkbaar beter zijn!

1. Strakke koppeling

Het probleem
Strakke koppeling is wanneer twee objecten zo afhankelijk zijn van elkaars gegevens en / of functies dat het modificeren van een ander de andere vereist. Wanneer twee objecten te strak gekoppeld zijn, kan het veranderen van code een nachtmerrie zijn en heb je meer kans om bugs te introduceren bij elke verandering.

Bijvoorbeeld:

klasmedewerker Bike bike = new Bike (); public void commute () bike.drive (); 

In dit geval zijn werknemer en fiets nauw met elkaar verbonden. Wat als je ooit op een dag een auto wilde rijden in plaats van een fiets voor je woon-werkverkeer? Je zou naar de Worker-klasse moeten gaan en alle Bike-gerelateerde code moeten vervangen door auto-gerelateerde code. Het is rommelig en vatbaar voor fouten.

De oplossing
Je kunt de koppeling losmaken door een laag abstractie toe te voegen. In dit geval wil de Worker-klasse niet alleen fietsen, maar ook auto's en misschien vrachtwagens, mogelijk zelfs scooters. Dit zijn allemaal voertuigen, nietwaar? Dus maak een Voertuiginterface, waarmee u verschillende Voertuigtypes kunt invoegen en vervangen zoals gewenst:

klasmedewerker Voertuigvoertuig; openbare leegte changeVehicle (Voertuig v) vehicle = v;  public void commute () vehicle.drive ();  interface Voertuig void drive ();  class Fietsgereedschappen Voertuig public void drive ()  class Auto implementeert Vehicle public void drive () 

2. God-objecten

Het probleem
Een God-object is een enorme klasse / module die te veel variabelen en functies bevat. Het “weet te veel” en “doet te veel,” wat om twee redenen problematisch is. Ten eerste worden andere klassen / modules voor deze gegevens te sterk afhankelijk van deze (strakke koppeling). Ten tweede wordt de algemene structuur van het programma modderig als alles op dezelfde plek wordt gepropt.

De oplossing
Neem een ​​God-object, scheid zijn gegevens en functies op basis van de problemen die er zijn om op te lossen en verander die groepen vervolgens in objecten. Als je een God-object hebt, is het misschien beter af als een compositie van veel kleinere objecten.

Stel dat je een monsterlijke gebruikersklasse hebt:

class Gebruiker public String gebruikersnaam; public String wachtwoord; public String-adres; openbare String-postcode; public int age; ... public String getUsername () gebruikersnaam teruggeven;  public void setUsername (String u) username = u; 

Je zou het in een samenstelling van het volgende kunnen omzetten:

class Gebruiker referenties credentials; Profielprofiel; ... class Credentials public String gebruikersnaam; public String password; ... public String getUsername () gebruikersnaam teruggeven;  public void setUsername (String u) username = u; 

De volgende keer dat u aanmeldingsprocedures moet wijzigen, hoeft u niet door een enorme gebruikersklasse te kruipen, omdat de Credentials-klasse beter te beheren is!

3. Lange functies

Het probleem
Een lange functie is precies hoe het klinkt: een functie die te lang is gegroeid. Hoewel er geen specifiek nummer is voor het aantal coderegels “te lang” voor een functie is het een van die dingen waar je het weet wanneer je het ziet. Het is eigenlijk een smallere versie van het God-objectprobleem - een lange functie heeft te veel verantwoordelijkheden.

De oplossing
Lange functies moeten in vele subfuncties worden onderverdeeld, waarbij elke subfunctie is ontworpen om een ​​enkele taak of probleem aan te pakken. Idealiter verandert de originele lange functie in een lijst met subfunctieaanroepen, waardoor de code schoner en gemakkelijker leesbaar wordt.

4. Overmatige parameters

Het probleem
Een functie (of klasse-constructor) die te veel parameters vereist, is om twee redenen problematisch. Ten eerste maakt het code minder leesbaar en moeilijker om te testen. Maar ten tweede, en wat nog belangrijker is, kan het erop wijzen dat het doel van de functie te dubbelzinnig is en te veel verantwoordelijkheden probeert aan te pakken.

De oplossing
Terwijl “te veel” is subjectief voor een parameterlijst, we raden aan alert te zijn op functies met meer dan 3 parameters. Natuurlijk is het soms logisch om een ​​enkele functie te hebben met 5 of zelfs 6 parameters, maar alleen als daar een goede reden voor is.

Meestal is er niet één en de code zou beter af zijn om die functie in twee of meer verschillende functies te breken. In tegenstelling tot de “Lange functies” code geur, deze kan niet worden opgelost alleen door code te vervangen door sub-functies - de functie zelf moet worden verdeeld en opgedeeld in afzonderlijke functies met betrekking tot afzonderlijke verantwoordelijkheden.

5. Slecht benoemde identificatiegegevens

Het probleem
Variabelenamen van één of twee letters. Nondescript-functienamen. Overmatig versierde klassenamen. Variabelenamen met hun type markeren (bijvoorbeeld b_isCounted voor een booleaanse variabele). En het ergste van alles is het combineren van verschillende naamgevingsschema's in een enkele codebase. Dit alles resulteert in moeilijk te lezen, moeilijk te begrijpen en moeilijk te onderhouden code.

De oplossing
Het kiezen van goede namen voor variabelen, functies en klassen is een moeilijk te leren vaardigheid. Als u lid wordt van een bestaand project, kam er dan doorheen en bekijk hoe bestaande identifiers worden genoemd. Als er een stijlgids is, onthoud deze dan en houd u eraan. Denk er bij nieuwe projecten over om je eigen stijlgids te maken en je eraan te houden.

Over het algemeen moeten variabelenamen kort maar beschrijvend zijn. Functienamen moeten meestal ten minste één werkwoord hebben en het moet meteen duidelijk zijn wat de functie doet, alleen maar uit de naam ervan halen, maar vermijd te veel woorden in een woord. Hetzelfde geldt voor klasnamen.

6. Magische nummers

Het probleem
Je bladert door een code die (hopelijk) iemand anders heeft geschreven en je ziet sommige hard gecodeerde nummers. Misschien maken ze deel uit van een if-statement, of maken ze misschien deel uit van geheimzinnige berekeningen die niet logisch lijken. Je moet de functie aanpassen, maar je kunt gewoon niet begrijpen wat de cijfers betekenen. Cue hoofd krabben.

De oplossing
Bij het schrijven van code, deze zogenaamde “magische nummers” moet ten koste van alles worden vermeden. Hardgecodeerde getallen zijn logisch op het moment dat ze worden geschreven, maar ze kunnen snel alle betekenis verliezen - vooral wanneer iemand anders probeert je code te behouden.

Een oplossing is om opmerkingen achter te laten die het aantal verklaren, maar de betere optie is om magische getallen om te zetten in constante variabelen (voor berekeningen) of opsommingen (voor voorwaardelijke instructies en switchinstructies). Door magische cijfers een naam te geven, wordt code in een oogopslag oneindig leesbaarder en minder gevoelig voor wijzigingen aan bugs.

7. Diepe nesten

Het probleem
Er zijn twee belangrijke manieren om te eindigen met diep geneste code: loops en voorwaardelijke uitspraken. Diep genestelde code is niet altijd slecht, maar kan problematisch zijn omdat het moeilijk te ontleden is (vooral als variabelen niet goed worden genoemd) en nog moeilijker te wijzigen is.

De oplossing
Als je merkt dat je een dubbele, driedubbele of zelfs viervoudige for-loop schrijft, probeert je code misschien te ver buiten zichzelf te komen om gegevens te vinden. Zorg er in plaats daarvan voor dat de gegevens kunnen worden opgevraagd via een functieaanroep van welk object of module de gegevens bevat.

Aan de andere kant zijn diep geneste voorwaardelijke uitspraken vaak een teken dat je te veel logica probeert af te handelen in een enkele functie of klasse. Sterker nog, diep nesten en lange functies hebben de neiging om hand in hand te gaan. Als uw code massale switchinstructies of geneste if-then-else-instructies bevat, wilt u mogelijk een State Machine- of Strategiepatroon implementeren.

Diep nestelen komt met name voor bij onervaren spelprogrammeurs. 5 Gratis spelontwikkelingssoftwaretools om je eigen spellen te maken 5 Gratis spelontwikkeling Softwarehulpmiddelen om je eigen spellen te maken Hier zijn de beste gratis spelontwikkelingssoftware en hulpmiddelen die je kunt gebruiken om je droomspel te maken vandaag. Lees verder !

8. Niet-verwerkte uitzonderingen

Het probleem
Uitzonderingen zijn krachtig maar gemakkelijk misbruikt. Luie programmeurs die verkeerd gebruik maken van throw-catch-statements kunnen exponentieel harder debuggen, zo niet onmogelijk. Bijvoorbeeld het negeren of begraven van gevangen uitzonderingen.

De oplossing
In plaats van gevangen uitzonderingen te negeren of te begrenzen, drukt u tenminste de stacktracering van de uitzondering af, zodat debuggers iets hebben om mee te werken. Uw programma stil laten falen is een recept voor toekomstige hoofdpijn, gegarandeerd! Geef ook de voorkeur aan specifieke uitzonderingen op algemene uitzonderingen. Lees meer in ons artikel over hoe om te gaan met uitzonderingen op de juiste manier Java-uitzonderingen op de juiste manier verwerken Hoe u met Java-uitzonderingen op de juiste manier omgaat In dit artikel leert u wat Java-uitzonderingen zijn, waarom ze belangrijk zijn, hoe u kunt gebruik ze en veelvoorkomende fouten om te voorkomen. Lees verder .

9. Dubbele code

Het probleem
U voert dezelfde exacte logica uit in meerdere niet-verwante gebieden van uw programma. Later besef je dat je die logica moet aanpassen, maar onthoud niet alle plaatsen waar je het hebt geïmplementeerd. Uiteindelijk verander je het in slechts 5 van de 8 plaatsen, wat resulteert in buggy en inconsistent gedrag.

De oplossing
Dubbele code is een uitstekende kandidaat voor het worden omgezet in een functie. Stel dat u een chattoepassing aan het ontwikkelen bent en u schrijft dit:

String queryUsername = getSomeUsername (); boolean isUserOnline = false; for (String gebruikersnaam: onlineUsers) if (gebruikersnaam.equals (queryUsername)) isUserOnline = true;  if (isUserOnline) ...

Ergens anders in de code, realiseer je je dat je hetzelfde moet doen “is deze gebruiker online?” controleren. In plaats van het kopiëren van de lus, kunt u deze uittrekken in een functie:

public boolean isUserOnline (String queryUsername) for (String gebruikersnaam: onlineUsers) if (gebruikersnaam.equals (queryUsername)) return true;  return false; 

Nu kunt u overal in uw code de isUserOnline () -controle gebruiken. Als u deze logica ooit moet wijzigen, kunt u de methode aanpassen en is deze overal van toepassing.

10. Gebrek aan opmerkingen

Het probleem
De code heeft absoluut nergens opmerkingen. Geen documentatieblokken voor functies, geen gebruiksoverzichten voor klassen, geen uitleg van algoritmen, enz. Men zou kunnen beweren dat goed geschreven code geen opmerkingen nodig heeft, maar de waarheid is dat zelfs de best geschreven code nog steeds meer mentale energie nodig heeft om begrijpen dan Engels.

De oplossing
Het doel van een eenvoudig te onderhouden codebasis moet een code zijn die goed genoeg is geschreven, maar die dat niet doet nodig hebben opmerkingen, maar heeft ze nog steeds. En als je opmerkingen schrijft, probeer dan commentaar te geven waarom een codefragment bestaat in plaats van uit te leggen wat het is aan het doen. Reacties zijn goed voor de ziel en geestelijke gezondheid. Negeer ze niet.

Hoe code te schrijven die niet ruikt

Zo duidelijk als het lijkt, de meeste code geuren komen voort uit een misverstand of verwaarlozing van goede programmeerprincipes en patronen. 10 Basisprincipes voor programmeren Elke programmeur moet 10 basisprincipes voor programmeren volgen Elke programmeur moet volgen Schrijf altijd code die kan worden onderhouden door iedereen die kan eindigen werken aan uw software. Daartoe zijn hier verschillende programmeerprincipes om je act op te ruimen. Lees verder . Bijvoorbeeld, een solide naleving van het DRY-principe elimineert de meeste codeduplicatie, terwijl beheersing van het Single Responsibility-principe het bijna onmogelijk maakt om monsterlijke God-objecten te creëren.

We raden ook aan ons artikel over het opschonen van schonere code te lezen. 10 Tips voor het schrijven van schonere en betere code 10 Tips voor het schrijven van schonere en betere code Schrijven schone code lijkt gemakkelijker dan het in werkelijkheid is, maar de voordelen zijn het waard. Hier leest u hoe u vandaag schonere code kunt gaan schrijven. Read More, dat naar een meer praktische kant van programmeren kijkt. Als u uw eigen code niet kunt lezen en deze in één oogopslag kunt begrijpen, hoe zal iemand anders dat dan doen? Schone code is geurloze code.

Waar worstelt u het meest mee als het gaat om programmeren? Deel het met ons in de reacties hieronder!

Beeldcredits: SIphotography / Depositphotos

Ontdek meer over: Programmeren.