web-dev-qa-db-fra.com

Pourquoi un générateur devrait-il être une classe interne plutôt que dans son propre fichier de classe?

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 Builderdevrait 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?

24
Nathanial

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.

30

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

1
AZ01