Tiens tu peux regarder ce lien qui te donnera déjà quelques explications, même si ce n’est pas la panacée.
Et on peut éventuellement analyser ton exemple de Pattern.compile(...)
vis à vis des arguments qu’il donne.
Allons voir dans les sources de Pattern.compile
:
public static Pattern compile(String regex) {
return new Pattern(regex, 0);
}
Là il fait donc appel à un constructeur privé :
private Pattern(String p, int f) {
pattern = p;
flags = f;
if ((flags & UNICODE_CHARACTER_CLASS) != 0)
flags |= UNICODE_CASE;
capturingGroupCount = 1;
localCount = 0;
if (pattern.length() > 0) {
compile();
} else {
root = new Start(lastAccept);
matchRoot = lastAccept;
}
}
```
Qui lui-même, dans le cas le plus courant (tu lui as donné un vrai pattern, de longueur > 0) fait appel à la méthode `compile` que je ne vais pas copier coller ici car elle est très longue.
Et c'est bien ça qui est important là-dedans, et souligné dans le lien que je t'ai donné plus haut.
La compilation d'un pattern est une opération assez coûteuse. `new Pattern(...)` ne donne pas énormément d'info sur le traitement qui pourrait être fait dans le constructeur. Par contre `Pattern.compile(...)` qui contient le mot "compile" éveille déjà un peu plus l'attention sur le fait que c'est une opération importante.
Autre chose, si on regarde bien ce qui est fait dans la méthode `compile` on voir certes beaucoup d'initialisations de champs ou propriétés du `Pattern`, mais tout plein d'optimisations et de vérifications, là où on préfèrerait conserver un constructeur pour l'initialisation "brute" de champs et propriétés.
Je dirais qu'une "règle de base" (*rule of thumb* ?) serait :
Si pour instancier ta classe, tu lui passes quelques arguments qui seront bêtement copiés dans les champs de ta classe (même si c'est un constructeur qui "copie" d'un objet à un autre) un constructeur fait l'affaire.
Exemple :
```java
class Complex {
public final int real;
public final int imaginary;
public Complex(int real, int imaginary) {
this.real = real;
this.imaginary;
}
}
Exemple type d’un cas où une factory statique serait intéressant : admettons que tu veuilles construire un pur réel, ou un pur imaginaire.
public Complex(int ???) { }
Tu vas avoir un conflit, les deux constructeurs "pur réel" et "pur imaginaire" vont avoir la même signature.
Pour lever l’ambiguïté, tu peux écrire deux méthodes statiques dans la class Complex
qui distinguent le cas du réel pur et de l’imaginaire pur. C’est le premier argument qui est avancé dans l’article que je t’ai donné.
etc.
Lis les autres arguments donnés dans le lien, et si tu n’en comprends pas certains on t’aidera !