Je veux développer un pipeline de filtre pour mon application. Le pipeline doit être constitué de n'importe quel nombre de filtres.
pour les filtres I Déclarez une classe de base abstraite comme celle-ci: p> Chaque filtre doit hériter de cette classe de base et de mettre en œuvre La méthode edit 1: strong> p> Le message doit être envoyé d'un filtre à l'autre dans le pipeline.
Si le pipeline, par exemple, est comme celui-ci: p> supérieure - printMessage - WriteToFile P> Le message doit passer tous les 3 filtres. (Par exemple, si dans l'exemple ci-dessus si le message edit 2: strong> p> Le filtre ne modifie que le contenu du message donné. Le type n'est pas changé. Chaque filtre doit fonctionner avec des ficelles ou une classe donnée.
Le message n'est envoyé qu'à un destinataire. P> Ma question est maintenant comment connecter ces filtres? P> Ma première hypothèse était d'utiliser My Devineuse devinait utiliser la chaîne de responsabilité et < Code> Boost :: signaux2 code>
Donc, filtrer par exemple se connecte au signal de filtrage. Filtera appelle ce filtre quand il a terminé son travail. P> Laquelle des deux solutions est la plus flexible? Ou existe-t-il même un meilleur moyen de connecter les filtres? P> Une question supplémentaire est-il également possible d'exécuter tout le pipeline à l'intérieur d'un fil afin que je puisse commencer plusieurs pipelines? (Dans l'exemple, 3 du pipeline filtrant-filtre-filtrant-filtrant UP et fonctionnent-ils?) P> p> exécuter code>.
Comme: p>
supérieur code> a terminé son travail, le message doit être envoyé à
PrintMessage code> et ainsi de suite) p>
Hello World Code> est envoyé au pipeline que la sortie doit être la sortie: p>
files d'attente code>. Donc, chaque filtre reçoit une entrée code> et
sortie code> la file d'attente. Pour cela, je pense que chaque filtre doit fonctionner à l'intérieur de son propre fichier
code> et d'être notifié si des données sont ajoutées à la file d'attente code> d'entrée code>. (La «file d'attente de la sortie code> code> de Filtera par exemple est également la
Entrée code> File d'attente de filtreB) p>
3 Réponses :
Je pense que AbstractFilter n'est pas nécessaire et je suggère d'utiliser STD :: Tuple pour définir un pipeline: pour exécuter un message via un pipeline DO (en utilisant c ++ 17 ): P> template<typename Pipeline>
void run_in_pipeline(const std::string& message, Pipeline& pipeline){
std::apply([&message](auto&& ... filter) {
(filter.execute(message), ...);
}, pipeline);
}
Merci pour la réponse, le filtre abstrait a été défini parce que je veux que le pipeline soit composé de filtre différent pouvant être défini dans un fichier de configuration afin que le pipeline soit créé de manière dynamique sur la configuration.
@Kevin Donc, s'il a le temps d'exécution configurable, un pipeline serait un vecteur des pointeurs à des filtres abstraits? Le run_in_pipeline réel serait une boucle. Si vous souhaitez éviter le pointeur de s'opposer aux raisons de performance, quelque chose d'autre sera nécessaire car même std :: Fonction alloue de manière dynamique la mémoire en interne ..
Je ferais de cette façon:
Créez une liste avec toutes les versions implémentées du filtre abstrait. Donc, après votre exmample, après avoir lu le fichier d'entrée, je recevrai une liste avec: puis un seul thread (ou un sondage de fil si vous devez traiter de nombreuses ficelles à l'heure) en attente d'un chaîne dans une file d'attente d'entrée. Lorsqu'une nouvelle chaîne apparaît dans la piscine, les boucles de thread sur la liste de filtres et à la fin publie le résultat dans une file d'attente de sortie. P> Si vous souhaitez l'exécuter en parallèle, vous devez trouver un moyen Pour conserver l'ordre des chaînes d'entrée Anche NELLE Stringhe DI Sortie. P> P>
J'ai bien peur que notre italien ne soit pas à la hauteur.
Je pense que le modèle de chaîne de responsabilité est plus simple, permet un code de nettoyage et une plus grande flexibilité. P>
Vous n'avez pas besoin de bibliothèques tierces pour la mettre en œuvre. Les étapes de pipeline en cours d'exécution en parallèle sont plus impliquées si certaines d'entre elles nécessitent la sortie des autres comme entrée. Pour que différents pipelines fonctionnent en parallèle, chacun fonctionnerait sur son propre thread et vous pouvez utiliser une file d'attente pour y passer des entrées. P>
Ce que vous appelez les filtres sont en réalité gestionnaires em>. Tous les gestionnaires mettent en œuvre une interface commune, définissant une méthode unique qui pourrait être nommée gérer () code> et pourrait même prendre un objet comme paramètre à partager l'état. Chaque gestionnaire stocke un pointeur au gestionnaire suivant. Il peut ou non appeler cette méthode à ce sujet; Dans ce dernier cas, le traitement est arrêté et agit comme un filtre em>. p>
Il y a un bon exemple dans Boost Asio: Github.com/ BOOSTORG / ASIO / BLOB / Développement / Example / CPP14 / Executor S / ... (aussi C ++ 11 GITUB.COM/BOOSTORG/ASIO/BLOB/Devop/Example/cpp11/Executor S / ... )
Cela pourrait être un bon candidat pour les coroutines si vous avez un compilateur qui le soutient. Je pense que les coroutines sont C ++ 20
Oui, j'ai aussi pensé à les utiliser, mais malheureusement, je ne pouvais pas utiliser de compilateur avec C ++ 20.
Vos filtres ne modifient pas ce qu'ils sont donnés du tout, je ne les appellerais pas aux filtres. Aussi, pourquoi forcer les gens à mettre en œuvre une autre base de base quand il n'y a qu'une seule fonction?
std :: fonction code> fournit suffisamment d'abstraction. Cela dit, je ne comprends pas vos exigences, c'est-à-dire quel comportement avez-vous besoin? Avez-vous besoin d'une commande? Une étape peut-elle terminer le pipeline?
@Ulricheckhardt désolé peut-être que les exemples ne sont pas si bons. Certains filtreurs doivent également être en mesure de modifier le message avant de les remettre. J'ai mis à jour les exemples.
Dans votre code, c'est la responsabilité du filtre de remettre le filtre suivant. Je préfère retourner le message changé. Ensuite, cependant, j'ai besoin de demander à nouveau: est-ce juste le contenu du message ou aussi le type qui change? En outre, je me demande si un filtre peut également transmettre à plus d'un autre filtre? Le cas qu'il n'envoie rien semble être manifestement nécessaire, mais s'il existe plusieurs destinataires, il semble que la réflexion sur les événements et les auditeurs d'événements seraient une meilleure approche. Pouvez-vous fournir un réel exemple d'utilisation?
@Lrichececkhardt Ce n'est que le contenu du message qui change. Pas le type. Chaque filtre doit fonctionner sur le même type (chaîne ou peut-être une classe). L'avant n'est que d'un destinataire.