Maison >Java >javaDidacticiel >Résumé de quelques problèmes courants dans la programmation Java

Résumé de quelques problèmes courants dans la programmation Java

高洛峰
高洛峰original
2017-01-16 16:17:271408parcourir

Cet article répertorie quelques erreurs typiques que j'ai vues dans le code Java de mes collègues autour de moi. Évidemment, l'analyse de code statique (notre équipe utilise qulice) ne pourra pas trouver tous les problèmes, c'est pourquoi je les liste ici.

Si vous pensez qu'il manque quelque chose, faites-le-moi savoir et je me ferai un plaisir de l'ajouter.

Toutes ces erreurs répertoriées ci-dessous sont essentiellement liées à la programmation orientée objet, en particulier la POO de Java.

Bien sûr, n'utilisez pas de préfixes ou de suffixes pour distinguer les classes des interfaces. Par exemple, ces noms sont erronés : IRecord, IfaceEmployee ou RecordInterface. D'une manière générale, le nom de l'interface doit être le nom de l'entité réelle et le nom de la classe doit décrire les détails de son implémentation. S'il n'y a rien de spécial dans l'implémentation, vous pouvez l'appeler Default, Simple ou quelque chose de similaire. Par exemple :

class SimpleUser implements User {};
class DefaultRecord implements Record {};
class Suffixed implements Name {};
class Validated implements Content {};

Nom de la méthode

La méthode peut renvoyer une valeur ou un vide. Si une méthode renvoie une valeur, son nom doit décrire ce qu'elle renvoie, par exemple (n'utilisez jamais le préfixe get) :

boolean isValid(String name);
String content();
int ageOf(File file);

Si elle renvoie void, son nom doit décrire ce qui a fait. Par exemple :

void save(File file);
void process(Work work);
void append(File file, String line);

Il n'y a qu'une seule exception aux règles que nous venons de mentionner : la méthode de test de JUnit ne compte pas. Ceci sera discuté ci-dessous.

Le nom de la méthode de test

Dans le cas de test JUnit, le nom de la méthode doit être une instruction anglaise sans espaces. Ce sera plus clair avec un exemple :

/**
 * HttpRequest can return its content in Unicode.
 * @throws Exception If test fails
 */
public void returnsItsContentInUnicode() throws Exception {
}

La première phrase de votre JavaDoc doit commencer par le nom de la classe que vous souhaitez tester, suivi d'une canette. Par conséquent, votre première phrase devrait être quelque chose comme « quelqu’un peut faire quelque chose ».

Le nom de la méthode est également le même, mais il n'y a pas de thème. Si j'ajoute un sujet au milieu du nom de la méthode, j'obtiens une phrase complète, comme dans l'exemple ci-dessus : "HttpRequest renvoie son contenu en unicode".

Veuillez noter que le nom de la méthode de test ne commence pas par can. Seuls les commentaires dans JavaDoc commenceront par can. De plus, les noms de méthodes ne doivent pas commencer par un verbe.

En pratique, il est préférable de déclarer la méthode de test pour lancer une exception.

Noms de variables

Évitez les noms de variables combinés, tels que timeOfDay, firstItem ou httpRequest. Cela est vrai pour les variables de classe et les variables au sein des méthodes. Les noms de variables doivent être suffisamment longs pour éviter toute ambiguïté dans leur portée visible, mais pas trop longs si possible. Le nom doit être un nom au singulier ou au pluriel, ou une abréviation appropriée. Par exemple :

List<String> names;
void sendThroughProxy(File file, Protocol proto);
private File content;
public HttpRequest request;

Parfois, si le constructeur souhaite enregistrer les paramètres d'entrée dans un objet nouvellement initialisé, les noms de ses paramètres et de ses attributs de classe peuvent entrer en conflit. Dans ce cas, ma suggestion est de supprimer les voyelles et d’utiliser des abréviations.

Exemple :

public class Message {
  private String recipient;
  public Message(String rcpt) {
    this.recipient = rcpt;
  }
}

Souvent, vous pouvez savoir quel nom doit être donné à la variable en regardant son nom de classe. Utilisez simplement sa forme minuscule, qui est fiable comme celle-ci :

File file;
User user;
Branch branch;

Cependant, vous ne devriez jamais faire cela avec des types de base, tels qu'un nombre entier ou une chaîne de caractères.

S'il existe plusieurs variables de natures différentes, vous pouvez envisager d'utiliser des adjectifs. Par exemple :

String contact(String left, String right);

Constructeur

Si les exceptions ne sont pas prises en compte, il ne doit y avoir qu'un seul constructeur utilisé pour stocker les données dans les variables d'objet. D'autres constructeurs appellent ce constructeur avec des paramètres différents. Par exemple :

public class Server {
  private String address;
  public Server(String uri) {
    this.address = uri;
  }
  public Server(URI uri) {
    this(uri.toString());
  }
}

Variables ponctuelles

Les variables ponctuelles doivent être évitées à tout prix. Ce que j'entends par « unique » ici, c'est une variable qui n'est utilisée qu'une seule fois. Par exemple, celle-ci :

String name = "data.txt";
return new File(name);

Les variables ci-dessus ne seront utilisées qu'une seule fois, ce code peut donc être restructuré comme ceci :

return new File("data.txt");

Parfois, dans de rares cas—— Principalement pour un formatage plus esthétique, des variables ponctuelles peuvent être utilisées. Cependant, cela doit être évité autant que possible.

Exception

Inutile de dire que vous ne devriez jamais avaler l'exception vous-même, mais devriez la laisser passer autant que possible. Les méthodes privées doivent toujours lever des exceptions vérifiées.

N'utilisez pas d'exceptions pour le contrôle des processus. Par exemple, le code suivant est erroné :

int size;
try {
  size = this.fileSize();
} catch (IOException ex) {
  size = 0;
}

Que dois-je faire si IOException affiche « disque plein » ? Pensez-vous toujours que la taille du fichier est de 0 et poursuivez-vous le traitement ?

Indentation

La règle principale concernant l'indentation est que la parenthèse ouvrante doit être soit en fin de ligne, soit être fermée sur la même ligne (l'inverse est vrai pour les parenthèses fermantes). Par exemple, ce qui suit est incorrect car le premier crochet ouvrant n’est pas fermé sur la même ligne et d’autres caractères le suivent. Il y a aussi un problème avec la deuxième parenthèse, car il y a des caractères avant elle, mais la parenthèse ouvrante correspondante n'est pas sur la même ligne :

final File file = new File(directory,
  "file.txt");

L'indentation correcte devrait être comme ceci :

StringUtils.join(
  Arrays.asList(
    "first line",
    "second line",
    StringUtils.join(
      Arrays.asList("a", "b")
    )
  ),
  "separator"
);

La deuxième règle importante concernant l'indentation est que vous devez essayer d'écrire autant de caractères que possible sur une ligne en même temps - la limite supérieure est de 80 caractères. L'exemple ci-dessus ne satisfait pas ce point, il peut aussi être réduit :

StringUtils.join(
  Arrays.asList(
    "first line", "second line",
    StringUtils.join(Arrays.asList("a", "b"))
  ),
  "separator"
);

Constantes redondantes

当你希望在类的方法中共享信息的时候,应当使用类常量,这些信息应该是你这个类所特有的。不要把常量当作字符串或数值字面量的替代品来使用——这是非常糟糕的实践方式,它会对代码造成污染。常量(正如OOP中的任何对象一样)应当在真实世界中有它自己的含义。看下这些常量在真实生活中的意思是什么:

class Document {
  private static final String D_LETTER = "D"; // bad practice
  private static final String EXTENSION = ".doc"; // good practice
}

另一个常见的错误就是在单元测试中使用常量来避免测试方法中出现冗余的字符串或者数值的字面量。不要这么做!每个测试方法都应该有自己专属的输入值。

在每个新的测试方法中使用新的文本或者数值。它们是相互独立的。那么为什么它们还要共享同样的输入常量呢?

测试数据耦合

下面是测试方法中数据耦合的一个例子:

User user = new User("Jeff");
// maybe some other code here
MatcherAssert.assertThat(user.name(), Matchers.equalTo("Jeff"));

最后一行中,”Jeff”和第一行中的同一个字符串字面值发生了耦合。如果过了几个月,有人想把第三行这个值换一下,那么他还得花时间找出同一个方法中哪里也使用了这个”Jeff”。


为了避免这种情况,你最好还是引入一个变量。

更多Java编程中的一些常见问题汇总相关文章请关注PHP中文网!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn