Why make donate

VoteCounting

author : Nolwenn Rannou <rannou@codelutin.com>
revision : 2613
date : 2009-06-30 15:32:57 +0200 (mar 30 jun 2009)

Cette partie décrit l'implémentation du module VoteCounting.

2 Interfaces existent :

  • ServiceVoteCounting : Service de gestion des dépouillements.
  • ServicePollExport : Service de gestion des exports d'un sondage et de ses résultats sous un format Standard,

ServiceVoteCounting

DTOVoteCounting

Les DTOVoteCounting (Data Transfert Object) permettent d'utiliser convenablement les interfaces proposés par le module VoteCounting.

Il y a deux DTO racines importants :

  • PollDTO : Correspond à un sondage et tous les éléments importants pour le dépouillement.
  • VoteCountingResultDTO : Le résultat du dépouillement organisé suivant les choix possibles du sondage.

PollExportDTO a été ajouté dans le cas d'un Import, il contient un PollDTO et plusieurs VoteCountingResultDTO.

Deux énumérations sont également disponibles et permettent la normalisation des types :

  • PollType : Type de sondage (Groupe, Libre, Restreint, ...)
  • VoteCountingType : Type de dépouillement (Condorcet, Pourcentage, ...)

A noté que le VoteCountingType sert de référence pour le dépouillement d'un sondage.

DTO du module VoteCounting

PollDTO

Il est composé de PollChoiceDTO qui sont les choix du sondage, et de CommentDTO qui sont les commentaires du sondage.

Il est composé de VotingGroupDTO. Ce dernier correspond à un groupe de votant dans le cas d'un sondage de type groupe. Il existera un et un seul groupe si le sondage est d'un autre type et aura des valeurs nulles à ses paramètres (weight et idGroup).

Chaque VotingGroupDTO est composé de VotingPersonDTO correspondant aux votants liés au sondage (personnes ayant votées). Le votingID sera égal à "anonymous" dans le cas d'un sondage anonyme.

Chaque VotingPersonDTO est composé de VoteToChoiceDTO correspondant aux votes du votant (pour chaque choix, une valeur).

A noté qu'il n'est pas nécessaire de connaître l'ensemble des choix à l'avance au niveau du sondage. Le dépouillement se chargera de réorganiser les résultats suivant les choix possibles.

VoteCountingResultDTO

Les résultats sont donc répartis suivant les choix possibles du sondage. Un ResultDTOV est donc composé de ChoiceDTOV correpondant à ces choix.

Nous avons donc pour un sondage donné :

  • le résultat global (VoteCountingResultDTO.choiceResult)
  • le résultat par choix (ChoiceDTO.value)

Operations

  • executeVoteCounting(poll : PollDTO) : VoteCountingResultDTO

Cette opération permet l'exécution du dépouillement d'un sondage.

  • executeGroupCounting(poll : PollDTO) : VoteCountingResultDTO

Cette opération permet l'exécution du dépouillement d'un sondage en fonction des groupes.

Implémentation

Le Pattern Strategy est utilisé pour gérer le dépouillement. Une classe Context permet de définir quel type de stratégie employé. La stratégie est définie dès le départ via l'attribut typeVoteCounting du PollDTO.

Ici les stratégies sont représentés par l'interface Method qui sera implémenté par :

  • CondorcetMethod : Dépouillement selon la méthode Condorcet
  • StandardMethod : Dépouillement simple
  • PercentageMethod : Dépouillement selon une pondération des choix

Chaque méthode implémente l'opération "executeMethod(choices)" qui sera appelé dans la classe Context par l'opération "execute()". Ainsi le contexte doit connaître l'ensemble des choix et des votes pour chaque choix et par groupe.

A l'appel du ServiceVoteCounting, un nouveau contexte sera créé et le PollDTO sera parcouru pour créer les choix, groupes et votes nécessaires au dépouillement qui sera executé.

Diagramme d'implémentation du service VoteCounting

Execution

  • Appel à executeVoteCounting
  • Création du contexte dépendant de PollDTO.typeVoteCounting
  • Parcours des PollChoiceDTO : Ajout des choix au contexte
  • Parcours des VotingGroupDTO : Pour chaque groupe -> VoteCounting.routeGroup(VotingGroupDTO) (avec ajout du groupe au contexte Context.addGroup(idGroup, weight))
  • Parcours des VotingPersonDTO : Pour chaque personne -> VoteCounting.routePerson(VotingPersonDTO)
  • Parcours du Vote : Pour chaque choix -> ajout au contexte via Context.getChoice(idChoice).getGroup(VoteCounting.currentIdGroup).addVote(value, weight)
  • Execution de la méthode de dépouillement -> Context.execute()
  • Création du VoteCountingResultDTO qui contient l'ensemble des choix avec leurs résultats
Diagramme de séquence de l'exécution d'un dépouillement simple (sans détails de l'algorithme)

Dépouillement Condorcet

Avec un système de vote classique, le vainqueur est le candidat qui possède le plus grand nombre de voix. Avec la méthode de dépouillement Condorcet ce n'est pas forcément le cas. Le vainqueur est celui qui, comparé à chaque autre candidat, est toujours préféré. Dans certaines situations un tel vainqueur n'existe pas, c'est ce que l'on appelle le paradoxe de Condorcet (A>B>C>A). L'algorithme choisi dans Pollen consiste à choisir le candidat qui a gagné le plus de confrontations. En cas d'ex aequo un vote doit être refait avec le groupe de tête. Le déroulement du vote par Condorcet est le suivant :

  1. Les votants classent les candidats par ordre de préférence
  2. Pour chaque vote, on compare les classements des candidats par paires et on compte le nombre de victoires de chaque candidat
  3. Le gagnant est celui qui possède le plus grand nombre de victoires

Dans Pollen, l'implémentation du vote par Condorcet comporte en plus la notion de groupes de votants. En cas de dépouillement par groupes, l'algorithme est appliqué au sein de chaque groupe. Ensuite l'algorithme est appliqué une seconde fois sur les résultats des groupes. Lorsque les votants participent à un vote, il leur est possible de classer deux choix à égalité. Il n'est pas nécessaire de classer tous les choix, ceux qui ne sont pas classés seront considérés comme derniers à égalité.

ServicePollExport

Operations

  • executeExport(export : PollExportDTO) : String

C'est l'opération principale qui permet l'export du sondage, l'objet passé en paramètre contien l'objet poll qui n'est que le sondage, et une liste des résultats à exporter ces résultat sont obtenus par les différents types de dépouillement. Cette méthode retourne le nom du fichier exporté.

  • executeImport(path : String) : PollExportDTO

Cette opération importe le sondage et ces résultats qui sont dans le fichier dont le chemin est passé en paramètre, donc reconstruit l'objet PollExportDTO, qui est retourné par cette opération.

Implémentation de l'export

Une simple implémentation a été faite pour cette partie, il s'avère que l'utilisation du pattern Visitor est significative pour l'implémentation de ce module vu qu'il fonctionne de la même manière que Visitor, cependant pour mettre cette possibilité en œuvre il va falloir ajouter des métodes aux classes DTOs ce qui viole leur sémantique, donc on a procédé comme montrer dans le schéma suivant.

Diagramme d'implémentation du service PollExport

Résultat d'un export

Pour concevoir le module d'export d'un sondage géré par l'application Pollen, il a fallu qu'on spécifie le résultat souhaité, pour ce faire on est parti sur une modélisation UML afin d'extraire l'architecture en arborescence de notre export, voir le diagramme de classe suivant :

Diagramme de classe de l'export d'un sondage et ces résultats