2017-07-16 3 views
0

Je crée une simple application de bloc-notes en Java et j'essaie d'utiliser un style fluide et immuable pour l'essayer. Je l'ai trouvé très amusant et je vois beaucoup d'avantages dont on parle en termes de programmation fonctionnelle (clarté du code, etc.).Gestion d'événements entre objets immuables

Mais j'ai un problème avec la gestion des événements en général. J'ai une classe TextArea qui fournit un document similaire à celui du bloc-notes. Ensuite, j'ai une autre classe ScrollBar. Ils sont manipulés par un MasterController de classe maître qui maintient la barre de défilement et la zone de texte fonctionnant ensemble (pas le vrai nom de classe, c'est juste pour cet exemple). Par conséquent, si l'utilisateur appuie sur la flèche vers le bas, CentralController appelle simplement TextArea.withDownArrow() et renvoie une nouvelle copie de TextArea avec le curseur déplacé vers le bas. Le problème est que la barre de défilement doit maintenant être déplacée, donc le CentralController doit savoir si le TextArea a été défilé par cette flèche vers le bas. Ma première tentative pour le résoudre était de retourner un objet qui contenait non seulement la nouvelle TextArea, mais aussi un drapeau indiquant si le défilement avait besoin d'être mis à jour. Cela a bien fonctionné mais je ne me sentais pas bien parce que je ne renvoyais plus le TextArea alors que vous devriez vraiment en programmation fonctionnelle "correcte" (grosso modo). Alors j'ai essayé d'avoir un drapeau dans TextArea qui serait défini si TextArea.withDownArrow() provoquait le défilement. Cela fonctionne également bien mais semble incorrect d'avoir un résultat de méthode stocké 'globalement' dans la classe. Il y a aussi des problèmes où vous pouvez appeler deux foisDownArrow(), puis le drapeau est remplacé par un nouveau résultat. J'ai lu un peu à propos de la programmation réactive et cela semble intéressant, mais je ne suis pas sûr que ce soit approprié pour cette situation où une classe 'enfant' envoie un message à un frère ou une sœur. Pour ajouter, je suis sous l'impression que la gestion normale des événements ne fonctionnera pas dans cette situation. Avec des objets immuables lorsque vous changez quelque chose, vous créez un nouvel objet. Ainsi, tous les objets qui tentent d'envoyer un événement à un écouteur enverront un ancien pointeur. Est-ce que je manque une manière évidente de faire ceci parce que je me sens comme je suis? Ou est-ce que c'est normal d'utiliser les techniques normales de gestion d'événements Java et je ne m'inquiète pour rien?

Edit: Je pense que j'ai trouvé une bonne solution maintenant. Même si la classe qui reçoit les événements (ScrollBar) est recréée tout le temps, les membres de cette classe ne sont pas recréés. Seulement les choses qui changent. Donc, je n'aurai qu'une simple méthode de réception d'événement dans ScrollBar, et TextArea peut avoir une liste d'écouteurs (essentiellement la façon «normale» de faire des événements avec des écouteurs).

En résumé, mon erreur pensait que je devais envoyer un événement à une instance plutôt qu'à un membre de cette instance.

Répondre

0

Vous devez différencier les objets de valeur et les objets logiques. Les objets de valeur ne contiennent que des valeurs, pas de logique (*). Ils peuvent être immuables.

Mais bien sûr, une zone de texte ne peut pas être un objet de valeur, et une barre de défilement ne peut pas non plus être un objet de valeur, car elle doit contenir de la logique. Ils ne peuvent pas non plus être immuables, car ils contiennent l'état. Alors, grattez tout ça. Ça ne marchera pas. (*) Ou au moins aucune logique qui traite des entités externes, ou manipule n'importe lequel de leur propre état.

+0

Juste pour être clair cependant, je retourne une toute nouvelle TextArea à chaque modification. Tout fonctionne actuellement assez bien (et fonctionne bien), mais je ne suis pas content des événements en particulier. De plus, ces objets font partie de mon modèle «pur» et la méthode de dessin d'écran est ailleurs et il suffit de regarder le modèle et de le restituer. – LegendLength