Pouvez-vous me faire comprendre facilement des objets d'événements abstraits dynamiques?

StackOverflow https://stackoverflow.com/questions/471144

  •  19-08-2019
  •  | 
  •  

Question

J'ai écrit des applications pilotées par événements C ++ à l'aide de MFC pour les boutons d'interface graphique, et j'utilise des événements HTML tels que onmousedown pour déclencher du Javascript dans une page Web. L'idée de la programmation événementielle est intuitive lorsque vous utilisez l'interface et les événements sont codés en dur.

Je sais comment utiliser un pointeur de fonction en C et je vois comment Windows les utilise pour exécuter une boucle d'événement. Je peux écrire du code pour appeler dynamiquement une fonction différente.

Mon problème est de passer de la compilation à l’exécution. Je parle n'importe quel langage ici, mais si vous avez besoin d'un langage, choisissez Javascript ou PHP, comme je les utilise le plus souvent. Je ne comprends pas du tout comment utiliser mon propre objet événement pour faire quelque chose. Ce n'est tout simplement pas un concept que je comprends. Et comme je ne les utilise pas, je ne sais pas quelle pourrait être leur utilisation pratique.

Par exemple, je suppose que si je voulais créer un jeu personnalisé au tour par tour, je pourrais utiliser des objets d'événement pour représenter un effet d'une capacité de pièce de jeu qui doit simplement "se produire".

Quelqu'un peut-il me donner une utilisation simple d’événements personnalisés? Ou des situations où cela est utile ou pratique? Est-ce que cela dépend en grande partie de la langue et de l'environnement et de la façon dont les événements sont gérés? Une réponse en Javascript serait bien, mais je lis beaucoup de langues.

Désolé, je suis simplement déficient à cet égard et j’ai besoin de connaissances approfondies pratiques (intermédiaires?). C'est comme des pointeurs en C. Je "récupère" pointeurs et comment ils sont votre ami. Mais il y a eu un temps où je ne l'ai pas fait et beaucoup de gens que je connais ne le sont toujours pas. C'est simple une fois que vous l'obtenez, je ne reçois pas les événements personnalisés et dynamiques de cette façon.

Était-ce utile?

La solution

Lorsque nous parlons de programmation orientée événement, nous parlons généralement d'une ou de plusieurs implémentations de motif de conception d'observateur . L’un des objectifs du modèle de conception de l’observateur est d’atteindre couplage lâche entre objets.

Cela ne veut probablement pas dire grand chose sans un bon exemple, et il y en a certainement beaucoup de bons; Je doute que les miens soient les meilleurs d'entre eux, mais je vais quand même y répondre. Imaginez deux objets. Un objet veut savoir quand quelque chose se passe avec l'autre objet, afin qu'il puisse faire quelque chose lui-même - peut-être que le chien de la famille, Rover, veut saluer papa à la porte lorsqu'il rentre du travail. Vous pouvez programmer ce scénario de plusieurs manières, n'est-ce pas?

  • Assurez-vous que papa a une référence à Rover et lorsqu'il rentre à la maison, appelez la méthode greetDatAtTheDoor () de Rover ou

  • Donnez à Rover une référence à papa, écoutez l'événement onArriveHome de papa, et quand il tire, appelez greetDadAtTheDoor () en interne.

En apparence, il ne semble pas y avoir beaucoup de différence entre les deux, mais en réalité, la mise en œuvre de Rover a été brûlée pour papa; si la mise en œuvre de Rover devait changer pour une raison quelconque, nous devions apporter des modifications à deux endroits: une fois dans Rover, puis une autre fois dans Papa. Pas très grave, peut-être, mais quand même pas idéal.

Maintenant, imaginez que maman veuille aussi saluer papa. Et le chat, M. Bigglesworth, qui n'aime pas beaucoup papa, veut s'assurer qu'il n'est pas là, alors il préfère sortir. Et un voisin, Joe, veut savoir quand papa rentrera à la maison, afin qu'il puisse le déranger à propos des vingt dollars que papa lui doit. Comment comptabiliser-t-on tous ces scénarios et les autres qui vont inévitablement se présenter? Placer des références à la méthode greetHusband () de maman, à la méthode getOutNow () du chat, à la méthode greetDadAtTheDoor () du chien, et à la méthode goGetMyMoney () de Joe dans la définition de classe de Dad ferait foirer les choses rapidement pour papa - et sans raison valable, car tout Papa a vraiment besoin de faire, lui-même, est rentré Maman, le chien, le chat et le voisin veulent juste être avertis lorsque cela se produit, afin qu'ils puissent faire ce que leur implémentation interne nécessite.

Les langues traitent les spécificités de ces éléments de différentes manières, mais comme vous le constaterez au début de la recherche sur Google, le modèle implique généralement la présence d'un tableau, ou d'une structure semblable à un tableau, sur l'événement " dispatcher " (dans ce cas, papa - c’est-à-dire l’objet qui intéresse tout le monde) et les "abonnés" (par exemple, Maman, le chat, Rover et Joe) tous "enregistrer" en appelant une méthode exposée publiquement sur le répartiteur et en transmettant des références à eux-mêmes - références qui se retrouvent, sous une forme ou une autre, dans le tableau d'abonnés de Papa. " Puis, quand papa rentre à la maison, il "expédie" un événement - le "je suis à la maison!" event, disons - qui est essentiellement une fonction qui parcourt chacun de ses abonnés et les invoque avec une méthode qui leur est accessible publiquement - seulement il s’agit d’une méthode dont papa ne connaît pas le nom, qui n’a pas à le savoir, car l'auditeur l'a fourni lorsqu'il l'a transmise.

Étant donné que je code principalement en ActionScript ces jours-ci, voici à quoi cela pourrait ressembler dans mon monde - par exemple, comme indiqué dans ma classe Mom:

var dad:Dad = new Dad();
dad.addEventListener(DadEvent.ARRIVED_HOME, greetHusbandAtDoor);

private function greetHusbandAtDoor(event:DadEvent):void
{
   // Go greet my husband
}

Alors, tout ce que je dois faire pour papa, quand je rentre à la maison, c'est:

dispatchEvent(new DadEvent(DadEvent.ARRIVED_HOME));

... et parce que Flash gère pour moi les détails de la répartition et de la notification des événements (là encore, tout le monde le fait un peu différemment, mais en interne, Flash suit le modèle conceptuel que j'ai décrit), mon père rentre à la maison et chacun membre de la famille fait

Autres conseils

Dans un langage compilé, vous écrivez votre propre boucle d’événement. Dans un langage d'exécution, il est déjà implémenté par l'environnement hôte et le programmeur obtient uniquement une interface abstraite dans le système d'événements. Vous ne voyez jamais la boucle d'événement.

Il existe deux facettes à la création de fonctionnalités avec des événements. La première consiste à définir les conditions dans lesquelles un événement se déclenchera. En javascript dans un navigateur, il n'y a pas un seul " mousedown " un événement. En fait, il y en a un pour chaque élément de la page. Dans ce cas, la condition pour que l'un d'entre eux se déclenche est basée à la fois sur l'emplacement du curseur de la souris et sur le fait que le bouton de la souris vient de passer de l'état haut à l'état bas. Cette condition peut déclencher plusieurs événements. (Dans le navigateur, il existe un événement appelé "bouillonnement" qui est lié à cela. Mais c'est hors de portée ici.)

L'autre facette est le gestionnaire d'événements. Un événement se produit, qu'il existe ou non un gestionnaire. Fournir le gestionnaire est à vous. En javascript, les fonctions sont des valeurs de première classe. Ils sont définis à l'exécution, pas à la compilation. Il n'y a donc pas besoin de pointeurs ni de tables de saut. Vous créez une nouvelle fonction au moment de l'exécution et vous l'affectez à une propriété spéciale que l'environnement hôte recherche lors du déclenchement d'un événement particulier.

Ainsi, en cas de débordement de pile, il y aura un gestionnaire d’événements sur chacune des flèches vers le bas "onclick". les événements, qui font tourner la flèche en rouge, décrémentent un nombre, vérifient une autre variable et affichent conditionnellement une notification. Ensuite, lorsque le gestionnaire renvoie le contrôle du fil au navigateur, l'utilisateur peut à nouveau interagir avec le navigateur. (Toutes les interactions cessent tant qu'un événement est géré, il est donc préférable de le rendre rapide). Voici un exemple utilisant la bibliothèque jquery.

jQuery("a .downarrow")
.click(function(e){ e.target.style.color="red" /* ... do other things */ });

ou javascript brut (version 1.6), il peut être

Array.prototype.slice.apply(document.getElementsByTagName("a"))
.filter(function(o){ return !!(/downarrow/).exec(o.className)})
.forEach(function(o){ 
    o.onclick= function(e){ 
        e.target.style.color="red" /* ...do other things * / 
    }
 });

C’est aussi simple que cela. La raison principale pour laquelle vous voulez faire quelque chose comme ceci est que cela permet une interaction asynchrone. Une application graphique ne progresse pas en ligne droite, pas à pas. Il doit répondre dynamiquement à l'entrée de l'utilisateur. Les événements sont un moyen de simuler l'apparence d'une application multithread. L’utilisateur peut penser que beaucoup de choses se passent simultanément sans s’interrompre mutuellement.

Vous pouvez utiliser une bibliothèque pour définir un événement personnalisé. Cela encoderait peut-être un événement spécifique à un domaine. Par exemple: vous avez un jeu d'échecs qui pense à son prochain coup. le processus de recherche du déménagement est terminé. Le jeu d’échecs pourrait déclencher un "onComputerMove". un événement. Vous pouvez gérer cet événement avec une fonction qui saisit les spécifications du déplacement, met à jour la représentation visuelle de l'échiquier et affiche un message à l'intention de l'utilisateur, puis se ferme. Ensuite, lorsque le joueur se déplace, vous pouvez déclencher un " onPlayerMove " événement, qui fait une grande partie de la même chose.

La chose la plus merveilleuse à propos des événements est de réduire le couplage explicite bidirectionnel entre deux modules ou classes.

Disons que j'ai deux cours: bébé et maman

Sans événement, je vois à peu près deux méthodes pour permettre à une maman de nourrir un bébé:

  • maman appelle la méthode baby.pokeBelly () sur le bébé toutes les demi-heures pour savoir si vous devez appeler baby.fillWith (lait) .
    Le problème est que le fil de maman doit attendre toute la journée après la boucle du bébé
  • Bébé connaît sa maman associée et appelle une méthode mommy.feed (moi) , qui appelle à son tour baby.fillWith (lait) .
    Le problème est alors de demander à un bébé simple de demander à la bonne maman de se remplir le ventre.
    Les bébés ne le font pas car ils doivent rester simples.

Avec les événements, vous pouvez lier un Mommy.OnBabyCries (bébé) à l'événement baby.Cry de son bébé:

void Mommy.OnBabyCries(baby) {
    baby.fillWith(milk)
}

Après cela, si bébé veut manger, tout ce qu’il a à faire est d’élever son événement Cry.

La logique reste dans la maman, ou même plus tard dans toute babysitter, et bébé reste heureux, sans avoir à s'inquiéter.

Je ne sais pas si je comprends tout à fait votre question, mais une classe avec un événement est comme une interface graphique avec un bouton. Pensez-y comme à un homonculus ... À l'intérieur de chaque classe d'un événement, il y a une petite personne avec un bouton virtuel à appuyer. Il ne sait pas ce que le bouton va faire, mais il sait quand appuyer dessus. Maintenant, pensez à un cours lié avec une autre petite personne. Cette personne sait que lorsqu'il entend un message indiquant qu'un bouton a été enfoncé, il est censé faire quelque chose.

Chaque fois que vous voulez que le deuxième gars sache quelque chose que le premier gars a fait, vous connectez le standard entre la première classe et la deuxième classe (s'abonner à l'événement). Lorsque le premier gars appuie sur le bouton (déclenche l'événement), le second fait ce qu'il sait qu'il est censé faire ...

Je ne sais pas si cela m'aidera ou si je suis simplement en voyage de concentration en pensant à de petites personnes minuscules dans mes programmes ...

Sur StackOverflow , lorsque vous votez vers le bas, votre réputation diminue et votre flèche bas devient rouge.

Généralement, vous écrivez un seul onclick , mettez à jour tous les éléments qu'il contient et essayez de ne pas oublier de le changer à chaque changement de mise en page.

Au lieu de cela, vous pouvez déclarer un événement onVoteDown , le déclencher dans onclick et vous abonner à cet événement:

  • votre réputation div
  • votre flèche img
  • votre XmlHTTPRequest qui envoie votre vote au serveur.

Je ne suis pas tout à fait sûr du type de réponse que vous recherchez, alors je vous prie de m'excuser si cela n'a rien de proche. ;)

Par personnalisé , voulez-vous dire actions personnalisées , des déclencheurs personnalisés ou véritablement événements personnalisés ?

Exemple: une action personnalisée répondrait à un événement prédéfini (par exemple, un clic de souris), un déclencheur personnalisé simulerait un clic de souris via un script et un événement personnalisé serait un écouteur qui n'est pas défini par le langage ou qui n'est pas facilement disponible.

Si vous recherchez des événements personnalisés , je ne peux pas vraiment vous aider. Cependant, je ne pense pas que JavaScript leur soit très utile.

Pour définir une action ...

Les événements sont normalement établis via les propriétés prédéfinies d'un objet, par exemple window.onload . Par défaut, ils sont tous égaux à undefined ou null . Donc, pour les utiliser, vous devez les définir sur la valeur d'une fonction.

Vous pouvez utiliser un fichier "anonyme". fonction:

window.onload = function (eventObject) {
    /* ... */
};

Ou définissez une référence de fonction (différente, mais similaire à un pointeur):

function handleOnload(eventObject) {
    /* ... */
}

window.onload = handleOnload; /* note the lack of parenthesis */

Lorsque l'événement est déclenché, la fonction est appelée. Ainsi, quelle que soit la configuration, lorsque le chargement de la page sera terminé, le code que vous placez à la place de / * ... * / sera exécuté.

Des méthodes plus formelles sont également disponibles pour créer des événements. Le W3C définit addEventListener alors que IE utilise attachEvent . Plus d'informations .

Il existe de nombreuses références disponibles pour apprendre la liste des événements disponibles. En voici 2 qui devraient vous donner une bonne base:

Le navigateur gère généralement le déclenchement d'événements - qu'il s'agisse d'événements du navigateur ( onload ) ou d'utilisateurs ( onclick ). La propriété et la fonction sont censées répondre.

Déclencher votre propre événement n'est pas la chose la plus facile à accomplir. Définir complètement un objet Event nécessite un certain travail - et varie selon les navigateurs. .

Toutefois, si vous n'avez pas besoin de l'objet Event , vous pouvez simplement appeler l'événement:

window.onload();
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top