Les données de Traction vs Push Approche de la programmation orientée objet
Quand je dessine, mon système à partir de zéro, j'ai souvent face à un dilemme si mon objet doit pousser de l'information dans une autre objets, OU si les objets doivent pull les données nécessaires à partir d'un autre objet.
Est-il quelque chose comme un standard dans la programmation orientée objet design, que je préférerais de données de traction par les objets, par rapport aux données de pousser dans les objets?
Peut quelqu'un d'expérimenté conseiller, si une approche est meilleure sur les autres à partir de à plus long terme point de vue, ou lors de la programmation orientée objet structure/cadre/diagramme devient de plus en plus complexe?
- GoF modèles de conception sont constitués d'assez spécifique problème et la solution. Ce n'est pas génériquement raisonnable d'être moins précis alors GoF. Sans la première partie, toute question n'a guère de sens. Et votre formulation des questions n'est PAS liée à C++.
- L'une des règles est de ne jamais copier ou de mettre en cache des données dans de multiples objets. Au lieu d'exposer des données comme getter (propriété) qui peut être consulté à l'aide de l'objet de référence. De cette façon, vous informent de l' (modèle Observateur) lorsque quelque chose change en passant de l'objet de référence ou une notification. Reste de l'accès devrait être à travers le getter de la propriété.
- Sergienko: Salut, et merci pour votre commentaire. Vous êtes parfaitement correct, que ma question est liée à la programmation orientée objet en général. Je vais vérifier GoF des modèles de conception, de voir ce qui est là.
- Si l'objet observé est complexe et l'observateur a besoin d'un indice, puis aller avec modèle push. Si l'objet observé est simple, un pull modèle fera l'affaire. E. g. Si l'objet observé est un employé avec 20 champs et observateur reçoit une notification de la part du sujet que l'employé de l'objet a changé, alors il fait sens pour objet observé à POUSSER les détails de la modification des champs dans une structure de données(e.g paires clé-valeur) à la place de l'observateur tirant ensemble de l'ensemble de données, puis faire des comparaisons stupides avec son état précédent pour savoir exactement ce que tous les champs modifiés. Choix doit être dicté par la situation.
Vous devez vous connecter pour publier un commentaire.
Selon dire ne pas demander, push est mieux - ou plus OO. Vous ne voulez pas pour objet de requête de données de sorte que vous pouvez faire quelque chose, vous voulez de l'objet pour le faire, parce qu'il est celui qui connaît ses données.
Article connexe sur le mal getters
Comme indiqué par d'autres réponses, ni pousser ni tirer est mieux, mais vous devez choisir celui qui correspond le mieux à vos besoins de conception.
De ici la question de savoir si un observateur modèle devrait être de pousser ou de tirer de base:
Pour ce modèle de la détermination de la caractéristique est la fréquence à laquelle les modifications de données, puis le taux correspondant à laquelle les observateurs souhaitent recevoir des données. Si les observateurs voulez que les données à un rythme plus lent que le sujet génère les données (un exemple serait le GPS sur un téléphone, vous n'avez pas besoin de votre position tout le temps, seulement quand vous avez une utilisation spécifique pour cela), alors l'interrogation est plus efficace. Si les observateurs veulent les données aussi rapidement que le sujet peut produire (un exemple possible serait un stock en temps réel, ticker application), puis les notifications push sont probablement mieux.
Je pense que la discussion ici est une sorte de manquer le point crucial à tirer et à pousser et il est coincé sur des exemples et des cas.
De la poussée : L'avantage de pousser, c'est que vous connaissez vos données, et vous savez ce que vous poussez. Aucun composant ne sait (ou ne devrait pas connaître) les données mieux que l'élément qui est le propriétaire des données, qui sera théoriquement implique un meilleur design et un système plus solide.
Tirant : Le seul avantage que je vois en tirant approche est le composant qui tire exactement sait quand il doit tirer. Il peut initier la conversation quand il a besoin des données et aucune composante ne sait pas (ou ne devrait pas connaître) lorsque les données est nécessaire que le composant qui a besoin d'elle.
Ma conclusion est: quel que soit le composant est propriétaire de la transaction, il initie la transaction. Si vous êtes à la récupération des données à partir d'une API, évidemment, l'API client propre à la transaction, il en sera de faire un pull. Si vous êtes à diffuser un message que le diffuseur est propriétaire de la transaction, de sorte qu'il ne est un push.
Il ne devrait pas être différent dans la programmation orientée objet (il y a peut être quelque chose que j'ai raté), mais une approche "pull", c'est mieux.
La raison pour laquelle je dis cela c'est parce que des tendances récentes dans les modèles de conception. Domain Driven Design et CQRS de très important, ils favorisent le couplage lâche qui est une très bonne chose.
Un objet ne devrait pas attention à ce que un autre objet ne avec ses données, il ne l'est pas de la responsabilité pour ainsi dire. L'objet doit seulement rendre les données disponibles et celles ayant besoin de les données d'extraction/de traction de l'objet. Regardez event driven design.
Elle fait l'objet indépendant de l'autre les objets et les rend plus portable (ne pas avoir à changer de où il pousse à l', puisqu'il est retiré de).
TL;DR je recommanderais tirer avec plus de pousser.
REMARQUE: tous ces différents modèles de conception ne marche pas exclure les uns les autres, mais coexistent.
destination.Pousser(source)
source.Pull(destination)
Choisir votre solution en regardant les dépendances que vous voulez avoir dans votre code.
Si la Source et la Destination ne peut pas dépendre de ce qui est nécessaire pour l'ancien régime, alors vous avez besoin de l'action à exécuter par une méthode externe qui sait (dépend) à la fois la Source et la Destination. Il a seulement l'accès du public à la fois si.
Si vous avez besoin d'virtuel ISource pour nourrir toute IDestination alors vous avez besoin de ces interfaces pour exposer toutes les méthodes nécessaires à une méthode externe pour effectuer l'action.
Si une seule méthode externe ne peut pas effectuer l'action sur toute ISource et tout IDestination, alors vous pourriez vouloir regarder le modèle Visiteur, le Visiteur de la classe de l'accomplissement de toutes les actions particulières sur la Source1 et SourceX Destination1 et DestinationY.
La réponse dépend de l'architecture des objectifs, en d'autres termes, il n'existe pas de solution générale.
Dans une architecture client /serveur, vous aurez probablement un système de couches sur le backend où les objets tirer de l'état à partir d'autres objets. Cela signifie que seulement certains "services" dans la mise à jour de fin de l'état d'un objet. Exemple: création d'un nouvel objet, mise à jour d'un champ d'un objet, etc. (Comme l'ajout d'un nouveau poste de commande pour le total de la commande).
Monolithique application de bureau, il pourrait être complètement différent. Il est probable que vous utilisez le "Modèle-Vue-Contrôleur" variations et observateur modèles etc. Dans ce cas, vous poussez info par exemple à l'INTERFACE utilisateur.
Généralement 'extraction de données' signifie que vous êtes en train de faire un appel ajax et de l'exécution d'un rappel sur le succès de sa réponse. Ce n'est pas mauvais, mais il peut être trop intensives si vous êtes à la vérification de mises à jour de données et sont donc de le faire sur un intervalle.
Mais dans le contexte d'une application web, une alternative est de pousser avec le temps d'interrogation. Depuis le temps d'interrogation n'est pas très différente de la première méthode, je vous propose de faire le suivant:
Créer un mode de scrutin qui extrait des données à partir d'un semi-publique pousser url de point de terminaison (aka un webservice pour pubsub), et ensuite mettre à jour tout ce qui doit être mis à jour via l'aide d'un éditeur-abonné modèle de conception de votre client. De cette façon, vos mises à jour sont plus découplée de la source de données.
Voici un livre blanc qui a été écrit sur ce sujet par IBM. http://www.ibm.com/developerworks/library/specification/ws-pubsub/
Le mot push/pull est relatif. Il y aura un poussoir qui les a données et qu'il sera d'un extracteur qui a besoin de données. Si nous avons effectivement stocker les données dans un lieu neutre, et non pas à l'intérieur de push-er/pull-er, de nombreuses possibilités de lever des qui convient à un problème donné dans le temps.On met à jour les données quand il a de l'(envoyer une notification si nécessaire) et l'autre tire les données à sa convenance.
De nombreux design patterns, MVC, Observateur, Commande, etc automne en place pour gérer le scénario.
D'abord, la règle générale est clairement: les objets sont données et comportement. Cela les encourage à moins que les accesseurs et donc moins tire en fournissant des méthodes qui ne quelque chose avec les données internes.
Seul "push est mieux" (dans l'acceptation de réponse) ne peut pas tout à fait comme un coup de pouce de l'opération dans une classe peut exiger une nouvelle traction à la poussée de l'objet. Au lieu de cela la meilleure pratique doit être l'ajout de l'opération push où il correspond à l'abstraction meilleur. Cela peut même mener à un nouveau plus abstraites de la classe et de la composition des classes (voir Conception Orientée Objet Heuristique, Riel, 1996, p. 37 f.).
De mon point de vue... Comme une application de bureau développeur en utilisant mvc, il y a une délicate balence où par vous pousser données lorsqu'il est disponible pour votre modèle d'objets, puis, sur la base de la logique dans le modèle (timers/événements asynchrones/notifications) les données sont ensuite poussés vers les contrôleurs et à son tour, à la vue... L'interface utilisateur interactions peut aller de toute façon en fonction de la préférence, ils peuvent déclencher une actualisation ou mise à jour du message qui indique au contrôleur qu'il doit faire quelque chose, ou il peut envoyer des données dans le contrôleur et souvent à tour de rôle le de modèle.
Bien sûr, c'est simplifiée et confondu par des scénarios du monde réel, mais d'avoir suffisamment de moyens à l'intention de le faire d'une manière particulière peut aller un long chemin.
@kamil-tomsik Que pensez-vous sur un client-serveur modèle, lorsque vous avez des centaines de clients qui ont le statut d'observateurs, mais ils n'ont pas besoin des mêmes données, donc si vous poussez, vous devez envoyer toutes les données que vous voulez partager, mais certains d'entre eux, n'en ont pas besoin. N'est-il pas ralentir la communication?
À partir d'une conception de point de vue, les données de traction est toujours une meilleure approche. La raison étant que toutes les informations doivent être récupérées, vous feriez mieux de faire des fonctions dans les classes qui renvoie les valeurs au lieu de pousser de l'information, qui n'est pas faux mais peut compliquer les sorties de la hiérarchie lorsque vous êtes dans l'utilisation du polymorphisme et de l'avancée des concepts de programmation orientée objet. Espérons que cela répond à votre question.