Mauvaises habitudes signalées dans les revues de code lorsque Java était débutant

Quand j'étais un nouvel employé débutant en Java, je me suis souvenu de ce que mes aînés avaient souligné dans la revue de code et je l'ai résumé.


Ajout: </ font> Nous avons reçu de nombreux commentaires utiles, y compris des avantages et des inconvénients, concernant cet article. Lorsque vous lisez cet article, veuillez également lire la section des commentaires.

2018/04/26 Correction du titre et du texte de "Essayer de rendre quelque chose constant" en référence aux commentaires. Merci, @kagilinn. 2018/04/30 Il y avait un bogue de jugement dans l'exemple de code, donc je l'ai corrigé. Merci d'avoir souligné, @y_miz. Correction des fautes de frappe dans les commentaires et les erreurs typographiques. Merci @scivola pour votre demande d'édition.

Créer des variables d'instance inutiles

Les variables d'instance conservent leur état, ce qui facilite la création de bogues. On a souvent souligné que "S'agit-il d'une variable locale?"

** Avant de créer une variable d'instance, vérifiez si elle peut être réalisée avec une variable locale. ** **

Tente de déclarer toutes les variables au début de la méthode

Cela semble être une habitude courante pour les personnes qui sont entrées en langage C. Le traçage est très fastidieux car la portée des variables s'élargit inutilement.

mauvais exemple


public String function() {
    int count;
    int max;
    int min;
    List fooList;
    String hogeCode;
    String fugaCode;
    String ret;
    
    //Traitement divers

    return ret;
}

** Déclarez les variables en tenant compte de la portée et en cas de besoin. ** **

Donnez un nom de variable insuffisamment expliqué

Il y a un débutant. Même les anciens combattants ont des personnes étonnamment adaptées. Les débutants ont tendance à faire des choses comme omettre le nom du modèle ou les numéros de série que seule la personne qui les a écrits connaît.

mauvais exemple


String str;  //Je sais seulement que c'est une chaîne

String code; //Je ne sais pas quel est le code

int a;       //Terrible mais rarement vu

File file1;  //Numéro de série mystérieux
File file2;

static final String MSGID_E0001 = "E0001"; //Il y a une valeur dans le nom de la constante

Bon exemple


String userName;

String messageCode;

int age;

File userListFile;
File companyListFile;

static final String MSGID_FILE_NOT_FOUND = "E0001";

Cependant, cela ne signifie pas que vous devez donner un nom de variable avec beaucoup de modifications à tout. Parfois, un nom court convient, comme un compteur dans une instruction for ou une exception interceptée.

** Le niveau de détail du nom de la variable dépend de la longueur de la portée. ** ** C'est une bonne idée de donner des noms détaillés aux variables d'instance et aux variables locales utilisées dans les méthodes longues. Inversement, si la portée de la variable est limitée à quelques lignes de blocs, un nom court de variable convient.

L'important est de pouvoir comprendre "ce qui est stocké dans cette variable" du point de vue du lecteur de code (y compris moi-même quelques mois plus tard).

La dénomination des variables semble facile et dans un monde très profond, Le célèbre livre "Readable Code" utilise également un nombre considérable de pages pour les noms de variables.

Utilisez xxxflg pour le nom de variable booléenne

Le gars qui n'a ressenti aucune gêne jusqu'à ce qu'il soit signalé. Avec xxxFlg, il est difficile de comprendre ce qui se passe quand c'est vrai.

mauvais exemple


private boolean writeFlg = false; //Vrai en tout cas/On ne sait pas si ce sera faux

Bon exemple


private boolean writable = false;

** Les noms de variables booléennes sont des propositions. ** ** Lorsque vous écrivez nom de variable == true, il est souhaitable que cela puisse être compris comme une instruction.

Exemple de nom de méthode


public boolean isWritable() {
    return writable;
}

En utilisant le nom de la méthode comme décrit ci-dessus, l'instance devient le sujet lors de l'appel, et la signification est facile à comprendre en tant que phrase anglaise.

if (note.isWritable()) { /* ... */ }

Certains des noms de méthodes les plus couramment utilisés sont:

--is + adjectif --can + verbe prototype --a + partie passée

  • Trois verbes simples (+ nomenclature)

[Référence] Un article résumant la dénomination des booléens du point de vue de la grammaire anglaise http://kusamakura.hatenablog.com/entry/2016/03/03/boolean_値を返却するメソッド名、変数名の付け方

Rendez-le constant sans donner de sens

Puisqu'il a été souligné que "l'écriture solide littérale est inutile", c'est un exemple de création de diverses constantes. Les constantes n'ont aucune signification, elles remplacent simplement les lettres.

private static final String HANKAKU_SPACE = " ";
private static final String BLANK = "";
private static final String COMMA = ",";
private static final String SLASH = "/";
private static final int ZERO = 0;

Essayez toujours de revenir à la fin de la méthode

Quand j'ai été signalé pour la première fois, je n'ai pas compris ce qui n'allait pas, J'ai bien compris quand j'étais en mesure de lire.

mauvais exemple


boolean isPrimeNumber(int num) {
    boolean ret;
    if (num < 2) {
        ret = false; //Moins de 2 n'est pas un nombre premier
    } else if (num == 2) {
        ret = true;  //2 est un nombre premier
    } else if (num % 2 == 0) {
        ret = false; //Les nombres pairs autres que 2 ne sont pas des nombres premiers
    } else {
        ret = true; //S'il n'est pas divisible, c'est un nombre premier
        double sqrtNum = Math.sqrt(num);
        for (int i = 3; i <= sqrtNum; i+=2) {
            if (num % i == 0) {
                ret = false;   //S'il est divisible, ce n'est pas un nombre premier
                break;
            }
        }
    }
    return ret; 
}

Bon exemple


boolean isPrimeNumber(int num) {
    if (num < 2) {
        return false; //Moins de 2 n'est pas un nombre premier
    }
    if (num == 2) {
        return true;  //2 est un nombre premier
    }
    if (num % 2 == 0) {
        return false; //Les nombres pairs autres que 2 ne sont pas des nombres premiers
    }
    double sqrtNum = Math.sqrt(num);
    for (int i = 3; i <= sqrtNum; i+=2) {
        if(num % i == 0) {
            return false;   //S'il est divisible, ce n'est pas un nombre premier
        }
    }
    return true; //S'il n'est pas divisible, c'est un nombre premier
}

Prenons le cas où un tiers trace le cas où 1 est entré dans num.

Dans le "mauvais exemple", comme on ne sait pas où le ret est réécrit, le lecteur doit lire l'état du ret et continuer la lecture jusqu'au retour final.

En revanche, dans le «bon exemple», chaque jugement revient sur place. Lors du traçage de la casse de num = 1, lisez jusqu'à revenir sur la troisième ligne.

Cet exemple est une méthode avec plus de 10 lignes, mais si vous implémentez une méthode avec 50 lignes et 100 lignes comme un "mauvais exemple", la charge sur le lecteur est incommensurable.

** La méthode doit retourner lorsque la valeur de retour est fixe **

De plus, le retour rapide présente l'avantage qu'il est difficile pour le nid de s'approfondir.

Essayez d'ajouter du public inutilement

En tant que débutant, j'ai tendance à rendre publiques les variables et méthodes privées. Tout d'abord, rendez-le privé et, si nécessaire, étendez-le à protégé et public.

Créez facilement des classes divines telles que xxxUtil, xxxHelper, xxxManager

Les classes dont les noms ne sont pas clairs sont dangereuses. C'est bon au moment de le faire, mais comme il est maintenu pendant 5 ans et 10 ans, les fonctions seront poussées ~ ~ ajoutées ~ ~ et cela deviendra intouchable.

Plus la partie xxx est abstraite, pire c'est. Le pire est CommonUtil. J'ai vu CommonUtil fabriqué il y a plus de 10 ans, et c'est plus de 4000 lignes.

Tout d'abord, il est bon de se demander s'il peut être changé en un nom tel que Factory, Builder, Writer, Reader, etc. qui limite le rôle **.

N'écrivez aucun commentaire

J'étais désespéré de l'implémenter, donc j'étais en colère si je le prenais à la révision du code sans écrire de commentaire.

Écrivons correctement les commentaires.

En particulier, ce qui suit devrait être complété par des commentaires.

  • Traitement ésotérique et branchement conditionnel compliqué
  • Circonstances et intentions spéciales qui ne peuvent pas être lues à partir du code

Rédigez des informations explicites sous forme de commentaire

Après m'être fait remarquer «Ecrire un commentaire», j'ai écrit un commentaire ligne par ligne, qui a également été signalé.

Si vous écrivez un commentaire ligne par ligne qui ressemble à une traduction japonaise du code, il sera bruyant. Étant donné que le nombre de lignes efficaces qui rentrent dans l'écran est réduit, la visibilité est également mauvaise.

mauvais exemple


//Obtenir l'ID utilisateur
String userId = user.getId();

//Ajouter un ID utilisateur à la liste
userIdList.add(userId);

Ne pas considérer 0 boucles

Lors de l'implémentation des instructions de boucle telles que les instructions for et while, nous n'avons pas supposé un cas où la boucle ne tournait pas même une fois, et il y avait des moments où un bogue était découvert dans le modèle 0-case du test unitaire.

Foo foo = null;
for (int i=0; i < hogeList.size(); i++) {
    if (i == 0) {
        foo = new Foo();
    }
    //En traitement
}
foo.function(); //NullPointerException se produit lorsque la boucle vaut 0 fois

** Lors de l'implémentation d'une boucle, supposez 0, 1 ou plusieurs modèles **

Négliger la conception des valeurs de retour de méthode et des exceptions

Malgré les méthodes publiques communes Les spécifications des arguments et des valeurs de retour étaient ambiguës.

Par exemple, les éléments suivants doivent être conçus sans omission et décrits dans Javadoc.

  • Que renvoyer si un nombre nul ou négatif est donné en argument ――Quand et quelle exception lancer ――Quand renvoyer null comme valeur de retour

Si vous voulez connaître un exemple de modèle de Javadoc, vous devriez jeter un œil à Javadoc of Oracle. La [méthode de classe de chaîne] familière (https://docs.oracle.com/javase/jp/8/docs/api/java/lang/String.html) sera facile à comprendre.

à la fin

Pour que les nouveaux programmeurs puissent écrire du bon code, sans parler de leurs propres efforts, Je pense qu'il est important d'obtenir des revues de code de bons programmeurs. Après avoir reçu les conseils du critique, "J'écrirais ceci pour moi-même", j'ai pris conscience que "Oh, y a-t-il une telle chose?" Grâce à l'accumulation, nous absorberons le savoir-faire et deviendrons capables d'écrire de meilleurs programmes.

Il y a des avantages et des inconvénients à utiliser les révisions de code comme lieu d'enseignement, À mon avis, la révision de code peut être une session d'étude ainsi qu'un effort d'amélioration de la qualité. Je reçois des suggestions et des conseils d'autres programmeurs pour le code que j'ai écrit, et j'en discute parfois. Une telle opportunité est peu probable, sauf pour les révisions de code. C'est trop inutile de simplement signaler un bug.

Recommended Posts

Mauvaises habitudes signalées dans les revues de code lorsque Java était débutant
Comment initialiser par lots des tableaux avec Java que je ne savais pas quand j'étais débutant
Code pour échapper aux chaînes JSON en Java
Une note quand vous voulez Tuple en Java
Lors de l'utilisation d'une liste en Java, java.awt.List sort et une erreur se produit
Ce que j'ai appris lors de la création d'un serveur en Java
Java11: exécuter le code Java dans un seul fichier tel quel
Différences de code lors de l'utilisation du système de longueur en Java
Résoudre l'erreur CreateProcess = 206 lors de l'exécution de Java dans un environnement Windows
[Débutant] J'ai créé un programme pour vendre des gâteaux en Java
Éléments à prendre en compte lors de l'écriture de code en Java
Rechercher un sous-ensemble en Java
Java avec Visual Studio Code
Écrire du code de type Java8 en Java8
Dans Java 10, lorsque l'éclipse gradle est terminée et que JavaSE-1.10 sort, ...
Évitez les erreurs de code de caractère en java lors de l'utilisation de l'extension VScode RUN-CODE