Je suis en train de lire sur le modèle Chaîne de responsabilité et j’ai du mal à imaginer un scénario dans lequel je préférerais l’utiliser plutôt que celui de décorateur .
Qu'est-ce que tu penses? Le CdR a-t-il une utilisation de niche?
Le fait que vous puissiez rompre la chaîne à tout moment différencie le motif Chaîne de responsabilité du motif Décorateur . On peut penser que les décorateurs exécutent tous en même temps sans aucune interaction avec les autres décorateurs. Les liens d'une chaîne peuvent être considérés comme s'exécutant un par un, car ils dépendent chacun du lien précédent.
Utilisez le modèle de chaîne de responsabilité lorsque vous pouvez conceptualiser votre programme comme une chaîne composée de liens, chaque lien pouvant gérer une demande ou la transmettre dans la chaîne.
Lorsque je travaillais avec l'API Win32, j'avais parfois besoin d'utiliser la fonctionnalité de raccordement qu'elle fournit. Accrocher un message Windows suit à peu près le modèle de chaîne de responsabilité. Lorsque vous avez raccroché un message tel que WM_MOUSEMOVE, votre fonction de rappel est appelée. Pensez à la fonction de rappel en tant que dernier maillon de la chaîne. Chaque lien de la chaîne peut décider de jeter le message WM_MOUSEMOVE ou de le transmettre au prochain lien.
Si le motif Decorator avait été utilisé dans cet exemple, vous auriez été averti du message WM_MOUSEMOVE, mais vous seriez impuissant à empêcher d'autres hooks de le gérer également.
Un autre endroit où le modèle de chaîne de commandement est utilisé est celui des moteurs de jeu. Encore une fois, vous pouvez accrocher des fonctions de moteur, des événements et d’autres choses. Dans le cas d'un moteur de jeu, vous ne voulez pas simplement ajouter des fonctionnalités. Vous souhaitez ajouter des fonctionnalités et empêcher le moteur de jeu d'effectuer son action par défaut.
La différence entre ces modèles ne dépend pas du moment ou de la manière dont la chaîne peut être rompue (ce qui suppose une chaîne) ni du moment où le comportement supplémentaire est exécuté. Ils sont liés en ce qu'ils utilisent tous les deux la composition en faveur de l'héritage pour offrir une solution plus flexible.
La principale différence est qu'un décorateur ajoute nouveau comportement qui élargit en fait l'interface d'origine. Cela ressemble à la manière dont l'extension normale peut ajouter des méthodes, sauf que la "sous-classe" est uniquement couplée à une référence, ce qui signifie que toute "super-classe" peut être utilisée.
Le modèle COR peut modifier un comportement existant, ce qui revient à remplacer une méthode existante à l'aide de l'héritage. Vous pouvez choisir d'appeler super.xxx () pour continuer la "chaîne" ou gérer le message vous-même.
La différence est donc subtile, mais un exemple de décorateur devrait aider:
interface Animal
{
Poo eat(Food food);
}
class WalkingAnimal implements Animal
{
Animal wrapped;
WalkingAnimal(Animal wrapped)
{
this.wrapped = wrapped;
}
Position walk(Human walker)
{
};
Poo eat(Food food)
{
return wrapped.eat(food);
}
}
class BarkingAnimal implements Animal
{
Animal wrapped;
BarkingAnimal(Animal wrapped)
{
this.wrapped = wrapped;
}
Noise bark()
{
};
Poo eat(Food food)
{
bark();
return wrapped.eat();
}
}
Vous pouvez voir que nous pouvons composer un animal qui marche et qui aboie ... ou qui ajoute la capacité d'aboyer à n'importe quel animal. Pour utiliser ce comportement supplémentaire directement, nous aurions besoin de conserver une référence au décorateur BarkingAnimal.
Tous les BarkingAnimal aboient également une fois avant de manger, ce qui a modifié les fonctionnalités existantes et est donc similaire à un COR. Mais l’intention n’est pas la même que celle de COR, c’est-à-dire de trouver un animal sur beaucoup qui mangera la nourriture. L'intention ici est de modifier le comportement.
Vous pouvez imaginer un COR appliqué pour trouver un humain qui emmènera l'animal en promenade. Cela pourrait être implémenté comme une liste chaînée comme chained
ci-dessus ou comme une liste explicite ... ou autre chose.
J'espère que c'est raisonnablement clair!
John
Chaîne
Évitez de coupler l'expéditeur d'une demande à son récepteur en donnant plus que un objet une chance de gérer le demande. Enchaîner les objets récepteurs et transmettez la demande le long de la chaîne jusqu'à ce qu'un objet le gère.
contre
Décorateur
Attribuez des responsabilités supplémentaires à un objet dynamiquement. Décorateurs fournir une alternative flexible à sous-classement pour extension fonctionnalité.
Je dirais que c'est dans l'ordre dans lequel les choses vont se passer. Si vous les enchaînez, ils seront appelés le long de la chaîne. Avec un décorateur, cette commande ne vous garantit pas que des responsabilités supplémentaires peuvent être attribuées.
Je dirais qu'une chaîne de responsabilité est une forme particulière de décorateur.
Decorator est utilisé lorsque vous souhaitez ajouter des fonctionnalités à un objet.
Le COR est utilisé lorsque l'un des nombreux acteurs peut agir sur un objet.
Un particulier Decorator est appelé à effectuer une action en fonction du type; pendant que COR transmet l'objet le long d'une chaîne définie jusqu'à ce que l'un des acteurs décide que l'action est terminée.
Le COR peut être utilisé lorsqu'il existe plusieurs niveaux d'escalade hiérarchique vers différents gestionnaires - par exemple, un centre d'appels où la valeur client de l'entreprise pour l'entreprise détermine si l'appel passe à un niveau de support particulier.
Eh bien, je peux penser à 2 situations:
Je ne peux plus en penser pour le moment, aimerions en entendre davantage sur ce sujet.
Décorateur
Decorator pattern permet d'ajouter dynamiquement un comportement à un objet individuel.
Il fournit une alternative flexible à sous-classification pour étendre les fonctionnalités. Même s'il utilise l'héritage, il hérite de l'interface du plus petit dénominateur commun (LCD).
Diagramme UML pour Decorator
Conséquences:
Liens utiles:
Quand utiliser le motif de décorateur?
Decorator_pattern de wikipedia
décorateur de sourcemaking
Chaîne de responsabilité: _
Le modèle de chaîne de responsabilité est un modèle de conception constitué d'une source d'objets de commande et d'une série d'objets de traitement. Chaque objet de traitement contient une logique qui définit les types d'objets de commande qu'il peut gérer. le reste est passé à l'objet de traitement suivant dans la chaîne
Diagramme UML
Ce modèle est plus efficace lorsque:
Liens utiles:
Chain-of-liability_pattern de wikipedia
modèle de chaîne de responsabilité de oodesign
chain_of_responsibility de la source
Exemple: : Dans une entreprise, un rôle désigné a des limites particulières pour le traitement de la demande d'achat. Si une personne ayant un rôle désigné n'a pas assez de pouvoir pour approuver une facture d'achat, elle transmettra la commande/demande à son successeur, qui dispose de plus de pouvoir. Cette chaîne continuera jusqu'à ce que la commande soit traitée.
Je conviens que du point de vue structurel, ces deux modèles sont très similaires. Ma pensée concerne le comportement final:
Dans l'interprétation classique de CoR, l'élément qui gère la demande rompt la chaîne.
Si un élément du décorateur casse la chaîne, alors ce sera faux implémentation de décorateur, car la partie de base du comportement sera perdue. Et l'idée de décorateur est l'ajout transparent d'un nouveau comportement lorsque le comportement de base reste inchangé.
Je pense que les situations pour appliquer ces deux modèles sont différentes. Et d'ailleurs, pour les motifs de décorateur, le décorateur doit connaître le composant qu'il a enveloppé. Et pour le CdR, les différents intercepteurs ne pouvaient rien se connaître.
Après avoir lu les définitions du Gang of Four, je ne suis pas convaincu qu'il y ait une réelle différence. (inclus pour plus de commodité)
Wikipedia les étoffe un peu, mais certaines sont un peu arbitraires.
Les deux premiers attributs ne distinguent pas vraiment les modèles. Les deux autres le sont, mais la manière dont Decorator et le CdR sont généralement mis en œuvre ne fait pas respecter ces attributs. Le concepteur espère simplement que personne n'écrira un décorateur rompant la chaîne ou un lien CoRLink qui poursuit la chaîne après le traitement des données.
Pour réellement implémenter ces attributs, vous aurez besoin de quelque chose comme ce qui suit.
Décorateur forcé:
abstract class Decorated {
public Decorated delegate;
public final Object doIt(Object args) {
Object returnVal = behavior(arg);
if(delegate != null) returnVal = delegate.doit(returnVal);
return returnVal;
}
protected abstract Object behavior(Object args); //base or subclass behavior
}
Chaîne de responsabilité forcée:
abstract class Link {
public Link delegate;
public final Object processIt(Obect args) {
Object returnVal = args;
if(isMyResponsibility) returnVal = processingBehavior(returnVal);
else returnVal = delegate.processIt(returnVal);
return returnVal;
}
protected abstract Boolean isMyResponsibility(Object args);
protected abstract Object processingBehavior(Object args);
}
(Alternativement, vous pouvez simplement ajouter une ligne au javadoc, si tout ce que vous voulez, c'est vous en décharger de toute responsabilité au cas où quelqu'un d'autre bousillerait votre conception - mais pourquoi laisser cela au hasard?)