Beaucoup Builder Pattern
les exemples font de Builder
une classe interne de l'objet qu'il construit.
Cela a un certain sens car il indique ce que le Builder
construit. Cependant, dans un langage typé statiquement, nous savons ce que le Builder
construit.
D'un autre côté, si le Builder
est une classe interne, vous devriez savoir quelle classe le Builder
construit sans regarder à l'intérieur du Builder
.
De plus, avoir le générateur comme classe interne réduit le nombre d'importations car il peut être référencé par la classe externe - si cela vous intéresse.
Et puis il y a des exemples pratiques où Builder
est dans le même paquet, mais pas une classe interne, comme StringBuilder
. Vous savez que le Builder
devrait construire un String
parce qu'il est nommé ainsi.
Cela étant dit, la seule bonne raison à laquelle je peux penser pour faire d'un Builder
une classe interne est que vous savez ce qu'est la classe 'Builder
sans connaître son nom ou en vous appuyant sur les conventions de dénomination. Par exemple, si StringBuilder
était une classe interne de String
j'aurais probablement su qu'elle existait plus tôt que moi (spéculative).
Y a-t-il d'autres raisons de faire du Builder
une classe interne ou est-ce simplement une question de préférence et de rituel?
Je pense que la raison de cela est que la classe interne (le constructeur) puisse accéder aux membres privés de la classe qu'elle construit.
De http://docs.Oracle.com/javase/tutorial/Java/javaOO/nested.html
Les classes imbriquées non statiques (classes internes) ont accès aux autres membres de la classe englobante, même si elles sont déclarées privées.
...
Considérez deux classes de niveau supérieur, A et B, où B a besoin d'accéder aux membres de A qui seraient autrement déclarés privés. En cachant la classe B dans la classe A, les membres de A peuvent être déclarés privés et B peut y accéder.
...
Comme pour les méthodes et variables d'instance, une classe interne est associée à une instance de sa classe englobante et a un accès direct aux méthodes et aux champs de cet objet.
Voici du code pour essayer d'illustrer cela:
class Example {
private int x;
public int getX() { return this.x; }
public static class Builder {
public Example Create() {
Example instance = new Example();
instance.x = 5; // Builder can access Example's private member variable
return instance;
}
}
}
En tant que classe statique, Builder n'a pas d'instance spécifique d'exemple à laquelle il est lié. Cependant, étant donné une instance de Example (ou une instance qu'il crée lui-même), Builder peut toujours accéder aux membres privés de cette instance.
Il n'y a pas de "devrait" dans ce cas. Définir un générateur dans une autre classe ou le séparer est orthogonal au modèle de générateur. De nombreux exemples le font en raison de la commodité de présenter le code dans un fichier cohérent (également pour accéder aux membres privés, mais cela dépend également du contexte). N'hésitez pas à faire autrement