Nous tous, en tant que développeurs, avons rencontré des situations où nous devons créer un objet. Le problème lorsque l’on tente de concevoir une classe générique pour cet objet est qu’elle peut prendre plusieurs formes. Un exemple simple : la classe User d'une plateforme. Pour un utilisateur régulier, nous n’aurons peut-être besoin que d’un e-mail et d’un nom d’utilisateur. Cependant, pour un administrateur de plateforme, des attributs supplémentaires comme un numéro de téléphone peuvent être requis. Nous pourrions également avoir un utilisateur Premium, où un champ supplémentaire comme un numéro de carte de crédit est nécessaire, et ainsi de suite.
Alors, comment peut-on procéder de manière générique ?
Face à ce problème, la communauté des développeurs s'est mise d'accord sur un modèle de création populaire : le Builder Design Pattern. Ce modèle consiste à séparer la construction d'un objet complexe de sa représentation, permettant ainsi de créer plusieurs variantes d'objet en utilisant le même processus de construction.
Ce modèle est particulièrement utile avec les objets qui possèdent de nombreux attributs, dont certains peuvent être facultatifs dans certains cas mais pas dans d'autres, ou pour les objets qui nécessitent un processus d'initialisation détaillé. Il permet la création flexible et étape par étape d'objets sans rendre le code trop complexe ni le constructeur trop surchargé.
Sections que nous couvrirons
Le Builder Design Pattern est particulièrement utile dans les cas suivants :
Si un objet possède de nombreux attributs, dont certains sont optionnels : Pour en revenir au problème que nous avons posé au début de cet article, considérons la classe User. D'après la logique que nous avons décrite, si nous instancions cette classe User, nous pourrions avoir différents cas : pour un utilisateur normal, normalUser = new User("houda", "houda@gmail.com", null, null), pour un admin adminUser = new User("houda", "houda@gmail.com", "0657...", null), et pour un utilisateur premium, premiumUser = new User("houda", "houda@gmail.com", nul, "1234..."). Cela entraîne de nombreuses valeurs nulles dans l'instanciation.
Objets avec un processus de création en plusieurs étapes : Un exemple est une classe Order. La première étape consiste à passer la commande, qui est ensuite préparée, puis enfin livrée. La préparation d'une commande peut nécessiter plusieurs étapes, et pour garantir le bon ordre de construction, le modèle de conception du constructeur est très utile.
Prise en charge de plusieurs représentations du même objet : par exemple, une classe Clothing qui possède des attributs pour le tissu, la couleur et la marque. Un vêtement peut être un pantalon, un t-shirt ou d’autres types. Ici, le modèle de constructeur permet de créer différentes représentations de la même classe de base.
pour chaque cas que nous avons vu dans la section précédente nous verrons la mise en œuvre du constructeur
class User { username: string; email: string; phoneNumber?: string; creditCard?: string; private constructor(builder: UserBuilder) { this.username = builder.username; this.email = builder.email; this.phoneNumber = builder.phoneNumber; this.creditCard = builder.creditCard; } public static get Builder() { return new UserBuilder(); } } class UserBuilder { username!: string; email!: string; phoneNumber?: string; creditCard?: string; public setUsername(username: string): UserBuilder { this.username = username; return this; } public setEmail(email: string): UserBuilder { this.email = email; return this; } public setPhoneNumber(phoneNumber: string): UserBuilder { this.phoneNumber = phoneNumber; return this; } public setCreditCard(creditCard: string): UserBuilder { this.creditCard = creditCard; return this; } public build(): User { return new User(this); } } // Usage const normalUser = User.Builder .setUsername("houda") .setEmail("houda@gmail.com") .build(); const adminUser = User.Builder .setUsername("houda") .setEmail("houda@gmail.com") .setPhoneNumber("0657....") .build(); const premiumUser = User.Builder .setUsername("houda") .setEmail("houda@gmail.com") .setCreditCard("1234....") .build();
class Order { private state: string; private constructor(builder: OrderBuilder) { this.state = builder.state; } public static get Builder() { return new OrderBuilder(); } public getState(): string { return this.state; } } class OrderBuilder { state: string = "Placed"; public prepareOrder(): OrderBuilder { if (this.state === "Placed") { this.state = "Prepared"; } return this; } public deliverOrder(): OrderBuilder { if (this.state === "Prepared") { this.state = "Delivered"; } return this; } public build(): Order { return new Order(this); } } // Usage const completedOrder = Order.Builder .prepareOrder() .deliverOrder() .build(); console.log(completedOrder.getState()); // "Delivered"
class Clothing { type: string; fabric: string; color: string; brand: string; private constructor(builder: ClothingBuilder) { this.type = builder.type; this.fabric = builder.fabric; this.color = builder.color; this.brand = builder.brand; } public static get Builder() { return new ClothingBuilder(); } } class ClothingBuilder { type!: string; fabric!: string; color!: string; brand!: string; public setType(type: string): ClothingBuilder { this.type = type; return this; } public setFabric(fabric: string): ClothingBuilder { this.fabric = fabric; return this; } public setColor(color: string): ClothingBuilder { this.color = color; return this; } public setBrand(brand: string): ClothingBuilder { this.brand = brand; return this; } public build(): Clothing { return new Clothing(this); } } // Usage const tShirt = Clothing.Builder .setType("T-Shirt") .setFabric("Cotton") .setColor("Blue") .setBrand("BrandA") .build(); const pants = Clothing.Builder .setType("Pants") .setFabric("Denim") .setColor("Black") .setBrand("BrandB") .build();
Le Builder Design Pattern est important pour plusieurs raisons clés, notamment lorsqu'il s'agit de gérer la complexité de la création d'objets. Voici pourquoi c'est si précieux :
Lorsqu'un objet possède de nombreux attributs, dont certains peuvent être facultatifs ou doivent être définis dans un ordre spécifique, le modèle de construction fournit une manière claire et structurée de créer l'objet.
En séparant la logique de création d'objet de l'objet lui-même, le Builder Pattern rend le code plus lisible et plus facile à maintenir.
Au lieu d'avoir plusieurs constructeurs avec différentes combinaisons de paramètres, le modèle Builder élimine le besoin de surcharge des constructeurs.
Le constructeur sépare la construction d'un objet de sa représentation. Cela signifie que vous pouvez modifier la façon dont l'objet est construit sans affecter sa représentation, ou vice versa.
Le Builder Design Pattern est un outil essentiel pour les développeurs chargés de la création d'objets complexes. En décomposant le processus de construction en étapes claires et gérables, il améliore la lisibilité, la maintenabilité et la flexibilité du code. Que vous travailliez avec des objets dotés de nombreux attributs, nécessitant une construction en plusieurs étapes ou devant prendre en charge plusieurs configurations, le modèle Builder fournit une solution élégante qui évite les constructeurs trop compliqués et réduit les erreurs.
Le blog couvert :
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!