Comment utiliser le mode decorator en PHP
Au fur et à mesure que nous progressons dans l’apprentissage de la programmation orientée objet (oop) en tant que développeurs PHP, l’utilisation de certains modèles établis devient plus importante, tout comme le modèle decorator que j’ai récemment utilisé. Au niveau du manuel, le schéma decorator nous permet de le modifier au moment de l’exécution de la classe, tandis que l’extension de la classe nous permet de le modifier au moment de la conception. Cette différence peut sembler insignifiante, mais elle a un impact important sur la lisibilité et l’extensibilité de l’application. Le schéma decorator est une autre façon d’ajouter des fonctionnalités à une classe. Au lieu d’utiliser l’hérédité pour l’étendre, nous avons créé une nouvelle classe qui est \
Voici un exemple rapide d’une classe de post représentant un événement qui modifie un post WP: Position = $position;
}
\/ * *
Obtenir la date de l’événement
* *
Chaîne de retour
* \/
Get _ Event date () {fonctions publiques
Retourner get _ post Meta ($this – > post – > ID, \
}
Le constructeur de cette classe accepte l’objet WP _ Post, donc nous avons ajouté une méthode pour obtenir la date de l’événement à partir du métachamp. Nous avons maintenant un objet déclaratif simple pour représenter la date de l’événement.
Le schéma decorator est logique ici, plutôt que d’étendre la classe WP _ post. L’une des raisons est subjective: Je pense qu’il est préférable de séparer les tâches de requête et de mise en cache de WP _ post de celles de cette catégorie: la date à laquelle l’événement a été obtenu. Une autre raison est réaliste. WP _ post est déclaré par le mot – clé final. Si une classe est déclarée avec un mot – clé final, il n’est pas possible de la Sous – catégoriser. Les motifs décoratifs offrent une solution à ce problème. Si je veux créer une classe pour un type particulier de post WordPress, je ne peux pas étendre WP _ post parce que
C’est la dernière leçon. Mais je peux le décorer.
Abonnement à l’interface {
Get _ Length () fonction publique: int;
Get _ plan () fonction publique: chaîne;
}
Abonnement à la classe
\/ * *
Var EDD \ u subscription
* \/
$abonnements protégés;
Fonction publique _ construction (EDD Subscription $Subscription)
{Y}
$this – > Subscription = $Subscription;
}
Get _ Length () fonction publique: int
{Y}
À faire
}
Get _ plan () fonctions publiques: chaîne
{Y}
À faire
}
}
Classe d’abonnement
\/ * *
Var Woo _ subscription
* \/
$abonnements protégés;
Fonction commune _ construction (abonnement $abonnement)
{Y}
$this – > Subscription = $subscription
}
Get _ Length () fonction publique: int
{Y}
À faire
}
Get _ plan () fonctions publiques: chaîne
{Y}
À faire
}
} la comparaison entre la décoration et les sous – classes, car c’est la seule option, ce n’est pas la seule raison pour laquelle nous utilisons des motifs décoratifs plutôt que des sous – classes. Souvent, lorsque j’écris du Code propre au site pour m’intégrer à d’autres plug – ins, j’étends leurs classes au lieu d’utiliser le schéma de décorateur le plus approprié.
Par exemple, voici une classe actuellement utilisée sur calderaforms. Com, pour enregistrer et invoquer notre champ de paiement personnalisé qui demande au client s’il achète un plug – in pour lui – même ou pour le client: Mise à jour _ Meta (self:: Organisation mondiale de la santé for Meta Key, $WHO);
$this – > add _ note (\
}
\/ * *
* Découvrez si c’est pour moi ou pour un client
* *
Chaîne de retour
* \/
Fonction publique get _ who for (): String
{Y}
$Chi = $this – > get _ Meta (self:: WHO for Meta key);
Si (NULL ($Chi) | | is _ String ($Chi) {
$who = ‘Customer’;
}
Renvoie $Chi;
}
Cette classe étend le paiement EDD en lisant et en écrivant ces données. Ça marche, mais je n’aime pas ce code.
Eh bien, je l’ai réécrit comme un décorateur. Ceci illustre la différence: Nombre de pages
To = $payment;
}
\/ * *
Destinations clés où nous stockons nos clients ou mes objets de paiement
* \/
Const World Health Organization _ for Meta key = \
\/ * *
Inscrivez – vous qui est payé en dollars
* *
* @ Param string $Chi indique qui c’est. Valeurs valides: me | client
* \/
Fonction publique set _ who for (String $who = ‘client’)
{Y}
Si (! In _ array ($Chi
\
« client»
()
) {
$who = ‘Customer’;
}
$this – > payment – > update _ Meta (self:: World Health Organization for Meta Key, $WHO);
$this – > payment – > add _ note (\
}
\/ * *
* Découvrez si c’est pour moi ou pour un client
* *
Chaîne de retour
* \/
Fonction publique get _ who for (): String
{Y}
$who = $this – > payment – > get _ Meta (self:: WHO for Meta key);
Si (NULL ($Chi) | | is _ String ($Chi) {
$who = ‘Customer’;
}
Renvoie $Chi;
}
Les paiements EDD sont maintenant considérés comme une dépendance. Cela signifie que la classe de paiement a un emploi. Le respect du principe de responsabilité unique ne vise pas seulement à obtenir de « bons points de codage ». Dans ce contexte, nous avons obtenu des résultats tangibles.
C’est plus facile à lire maintenant parce que nous n’avons pas à nous soucier de comprendre les parents. De plus, il est plus facile de modifier l’analogie de la décoration pour l’étendre à d’autres classes. Tout à cette échelle est insignifiant. Mais à mesure que la complexité de la fonctionnalité personnalisée augmente, la classe représente en fait un contenu très différent de celui sur lequel elle est basée. Par exemple, dans Caldera forms pro, un produit SaaS partiellement intégré dans WordPress, le logiciel utilise des téléchargements numériques simples pour le commerce électronique. Dans ce code, j’a I une classe d’abonnement qui décore la classe d’abonnement EDD \ U. J’ai pris cette décision de conception pour plusieurs raisons. Tout d’abord, mon objet d’abonnement fonctionne très différemment de la classe d’abonnement EDD \ U. Je ne crée pas d’abonnement ou de base de données.
Obtenez des renseignements de base sur les clients et des métadonnées propres à mon application.
Bien que j’aime compter sur des téléchargements numériques faciles, cela peut changer, ou je peux ajouter d’autres façons de créer des abonnements. Si nécessaire, je peux utiliser la même méthode commune pour créer différentes classes et décorer différents objets. Ils sont interchangeables avec le monde extérieur, mais complètement différents en classe. Ces approches communes clés devraient être définies dans les interfaces mises en œuvre par les deux parties. Voici un exemple de la façon de rendre la logique interne invisible. J’a I une interface d’abonnement et deux classes qui l’implémentent. Un abonnement à la décoration Woo _ et un abonnement à la décoration EDD abonnement
Abonnement à l’interface {
Get _ Length () fonction publique: int;
Get _ plan () fonction publique: chaîne;
}
Abonnement à la classe
\/ * *
Var EDD \ u subscription
* \/
$abonnements protégés;
Fonction publique _ construction (EDD Subscription $Subscription)
{Y}
$this – > Subscription = $Subscription;
}
Get _ Length () fonction publique: int
{Y}
À faire
}
Get _ plan () fonctions publiques: chaîne
{Y}
À faire
}
}
Classe d’abonnement
\/ * *
Var Woo _ subscription
* \/
$abonnements protégés;
Fonction commune _ construction (abonnement $abonnement)
{Y}
$this – > Subscription = $subscription
}
Get _ Length () fonction publique: int
{Y}
À faire
}
Get _ plan () fonctions publiques: chaîne
{Y}
À faire
}
} mieux encore, le reste du programme ne se préoccupe pas de la différence entre la façon dont woocommerce et Easy Digital downloads traitent les abonnements. Cette logique devient une boîte noire. Cette façon d’implémenter le schéma et l’interface du décorateur permet au projet de s’intégrer à plusieurs plug – ins ou API du même type, tels que les plug – ins de commerce électronique, les passerelles de paiement, etc. Plus facile à gérer.
Faiblesse
Si c’est la seule option. Mais les sous – classes sont souvent une option, et je ne dis pas que ce n’est pas bon. Je veux dire, il a des inconvénients, et en étudiant une autre option, nous pouvons évaluer ce qui est le mieux dans chaque cas – sous – classe ou décoration – et décider ce qui est le mieux dans ce cas.