2

J'essaie de réécrire du code pour résoudre certains problèmes de couplage et faciliter les modifications ultérieures.Modèle pour lequel un seul gestionnaire devrait agir en fonction de la spécialisation

En ce moment, j'ai une méthode statique usine dans une classe de base qui, en fonction de la situation, prend une appropriée mise en œuvre. La décision est basée sur les diplômes de spécialisation :

Bien que les types A et B les deux peuvent gérer cela, B a été conçu spécifiquement pour cette situation et est le bon choix.

La classe de base est donc couplé intimement avec toutes les implémentations et cette méthode doit être réécrite lorsque de nouvelles implémentations spécialisées sont créées.

Je songe à utiliser le modèle Chain of Responsibility pour rompre ce couplage. Cependant, je ne peux pas voir un moyen de s'assurer que l'implémentation la plus qualifiée s'exécute. Si je le cède aux implémentations pour faire cette détermination, je ne peux pas garantir qu'elles seront interrogées dans l'ordre de spécialisation sans rencontrer les mêmes problèmes de couplage.

Existe-t-il des modèles ou des méthodes pour gérer des situations comme celle-ci? (Ma meilleure estimation entraverait le déploiement, je vais le garder dans ma poche arrière de peur que tout le monde dise "oui, c'est la seule façon de le faire!")

Répondre

0

Vous devez créer une implémentation particulière parmi les nombreuses disponibles sur certaines données d'exécution - cela ressemble à la Abstract Factory pattern.

+0

Ce n'est qu'une partie de la solution. La partie la plus facile, malheureusement. Comment quantifier leur capacité à gérer une situation sans connaître leur implémentation et ensuite la comparer avec les capacités d'autres implémentations sans connaître toutes les situations et variables possibles à l'avance est la partie collante. – Will

+0

@Will: Je vois le coeur de votre question. Vous essayez de déterminer comment bouillir "peut gérer cette situation" jusqu'à une valeur numérique qui peut être associée à chaque mise en œuvre. Je demande en réponse: quel problème vous résolvez qui nécessite ce mécanisme? –

+0

Je voudrais pouvoir le réduire à un certain nombre! Sans entrer dans les détails, j'essaie d'interagir avec différentes fenêtres. Je dois gérer, disons, les fenêtres IE différemment que, par exemple, les fenêtres d'applet Java. Et si aucun ne s'applique, alors comme une vieille fenêtre Win32 simple. Plus je connais une fenêtre (ce qui est un processus complexe dépendant du type de fenêtre), mieux je peux le gérer. Il peut éventuellement s'étendre à l'application qui possède la fenêtre. Je ne peux pas rester en dehors du processus et choisir le meilleur gestionnaire sauf si je sais quel type de fenêtre, et cette connaissance est liée dans le gestionnaire. – Will

2

Si vous avez un moyen de quantifier comment une implémentation peut gérer une situation spécifique, vous pouvez utiliser une variante de la chaîne de responsabilité.

Les implémentations individuelles pourraient fournir un classement quantifié de leur capacité à gérer un ensemble donné d'entrées, et vous pourriez utiliser ce classement pour choisir la «meilleure» implémentation à utiliser. Cependant, ce n'est pas forcément une conception géniale - elle apporte beaucoup de confiance aux différentes implémentations et les oblige à être «honnête» quant à la façon dont elles peuvent gérer une situation spécifique. Il est également toujours possible d'entrer dans une situation où plusieurs implémentations signalent la même valeur, dans laquelle vous pouvez choisir un moyen de sélection.

1

Si vous pouvez définir une sorte de fonction de commande appropriée pour chaque cas, vous pourriez avoir chaque registre classe son auto avec un type usine spécifique et trier en fonction de ce qui suit:

class Base; 
class CaseInfo; 

class TypeFactory { 
public: 
    virtual Base MakeOne(); 

    //... Anything needed to implement Compare 
} 

// each derived type must inject a instance into AllTypes 
dequeue<TypeFactory> AllTypes; 

bool Compare(const TypeFactory&, const TypeFactory&, const CaseInfo&); 
Base Best(const CaseInfo&); 

La seule question que je peux penser de est que Compare sera non-trivial. Pour tout CaseInfo, il doit uniquement sélectionner une meilleure correspondance. L'astuce sera de sélectionner le bit "Anything else".

0

Je ne suis pas sûr que la chaîne de responsabilité puisse être modélisée comme ceci. Les gestionnaires de la chaîne de responsabilité ne peuvent faire que deux choses. Traitez la demande ou passez-la au gestionnaire suivant. Il ne sait pas quel gestionnaire est le suivant ou qui doit traiter la demande, il sait seulement qu'il ne peut pas.

Vos gestionnaires doivent être plus sélectifs. Si vous avez un gestionnaire que vous souhaitez gérer les fenêtres IE et un pour gérer l'application Java, les deux gestionnaires doivent être en mesure de détecter le type de fenêtre qu'ils traitent. Le gestionnaire IE vérifie si la fenêtre est IE si elle ne le passe pas, il ne se soucie pas si elle est traitée ailleurs, elle sait juste qu'elle ne peut pas le gérer.

Ma suggestion, faire des gestionnaires spécifiques qui ne traitent que 1 type de fenêtre. Créez un gestionnaire générique. Ensuite, commandez les gestionnaires pour que le gestionnaire générique soit le dernier. Tout gestionnaire spécialisé tentera de l'exécuter en premier, si aucun gestionnaire générique ne traite la requête.

Si vous vouliez vraiment faire ce que vous suggérez, vous pouvez faire plusieurs passes pour les gestionnaires. Pass 1 seulement des fenêtres très spécialisées se font prendre. Passez 2 fenêtres moins spécialisées se faire attraper. Etc etc jusqu'à ce que vous êtes fatigué de faire des passes. Cependant, pour moi ... je dis, ne pas essayer de faire beaucoup avec 1 gestionnaire. Si chaque gestionnaire est responsable de 1 fenêtre alors l'ordre n'a pas d'importance, ils vont toujours gérer le type de fenêtre correct. Toute fenêtre inconnue sera interceptée par le gestionnaire générique.

1

La solution peut être un hybride de chaîne de responsabilité et un modèle de visiteur. le visiteur peut résumer quelques-uns des aspects comportementaux communs.

+0

Hmmm, intéressant. Je souhaite que vous élaboriez sur ceci, ce pourrait être la meilleure réponse. – Will

+0

Toutes mes excuses! Je serai un peu plus précis. Je pense que le visiteur peut encapsuler la logique de décider de la meilleure mise en œuvre. Les nœuds individuels peuvent propager le vistor. Pensez-y comme un groupe de nœuds ayant chacun sa propre implémentation. Le nœud sait ce qu'il faut faire. La visiteuse visite chaque nœud et s'y attache si elle peut évaluer la meilleure implémentation avec certaines informations fournies par le nœud. Si l'évaluation ne convient pas, le nœud pousse le vistor sur le nœud suivant de la chaîne. – zerodin

Questions connexes