제이온

[Effective Java] Item 2. Envisager un constructeur pour les nombreux paramètres du constructeur

Création: 2024-04-27

Création: 2024-04-27 00:46

Modèle de constructeur progressif

Les usines statiques et les constructeurs ont tous deux du mal à gérer correctement un grand nombre de paramètres. Par exemple, si une classe a 6 champs et que nous voulons créer un constructeur avec 2 paramètres, un autre avec 3, etc., nous pouvons utiliser le modèle de constructeur progressif comme suit.



Cependant, même avec cette approche, si le nombre de paramètres augmente, la lecture du code peut devenir difficile, car il est difficile de comprendre le sens de chaque valeur et il est possible de confondre des paramètres de même type lors de leur affectation.


Modèle JavaBeans

Le modèle JavaBeans crée un objet à l'aide d'un constructeur sans paramètre, puis appelle les méthodes setter pour définir les valeurs des paramètres souhaités.



Le modèle JavaBeans permet de créer des instances sans confusion, même avec un grand nombre de paramètres. Cependant, la création d'un objet nécessite plusieurs appels de méthodes setter et la cohérence est compromise tant que l'objet n'est pas complètement construit. Par conséquent, la classe ne peut pas être rendue immuable.


Modèle Builder

Le modèle Builder est principalement utilisé car il combine la fiabilité du modèle de constructeur progressif et la lisibilité du modèle JavaBeans.

Au lieu de créer directement l'objet souhaité, le client appelle le constructeur avec uniquement les paramètres obligatoires pour obtenir un objet Builder. Ensuite, il utilise les méthodes setter fournies par l'objet Builder pour définir les paramètres facultatifs souhaités. Enfin, il appelle la méthode build(), qui ne prend aucun paramètre, pour obtenir l'objet souhaité.



Le constructeur de la classe Builder prend uniquement les paramètres obligatoires en entrée, et les autres paramètres facultatifs sont définis via des méthodes setter. Enfin, la méthode build() est utilisée pour créer l'objet NutritionFactsWithBuilderPattern complet. La classe NutritionFactsWithBuilderPattern est immuable et les méthodes setter du Builder renvoient le Builder lui-même, ce qui permet des appels en chaîne. Cette technique est appelée API fluide ou enchaînement de méthodes.



Du point de vue du client, le modèle Builder simplifie l'écriture et la lecture du code.


Le modèle Builder est bien adapté aux classes hiérarchiques


La classe Pizza.Builder est un type générique utilisant une liaison de type récursive et inclut une méthode abstraite self() pour permettre aux sous-classes de prendre en charge l'enchaînement de méthodes sans conversion de type. Dans les sous-classes, la valeur de retour de cette méthode abstraite doit être définie sur elle-même.

Examinons maintenant les pizzas de New York et les calzones, qui sont des sous-classes de Pizza, pour découvrir la flexibilité du modèle Builder.



La méthode build() définie par le constructeur de chaque sous-classe renvoie la sous-classe concrète. La capacité d'une méthode d'une sous-classe à renvoyer un type qui est un sous-type du type renvoyé par la méthode de la classe parente est appelée typage de retour covariant. Grâce à cette fonctionnalité, le client n'a pas besoin d'effectuer de conversion de type.



Le client peut utiliser l'énumération Pizza et les énumérations de chaque sous-classe simultanément et créer des objets en utilisant les méthodes appropriées pour chacun.


Inconvénients du modèle Builder

  • Nécessité de créer un objet Builder.
  • Le code est verbeux.


Résumé

Si un constructeur ou une méthode d'usine statique doit gérer un grand nombre de paramètres, envisagez d'utiliser le modèle Builder.


Sources

  • Effective Java

Commentaires0