TP Commit question 3

Programmation Avancée

Modérateur : Douin

Répondre
TSwank
Messages : 15
Inscription : 05 juin 2014 11:03

TP Commit question 3

Message par TSwank » 02 déc. 2016 12:49

Bonjour,

J'ai un soucis avec la méthode de test testDebitEnErreur :
En effet, celle-ci n'utilise pas de classe transactionnelle pour effectuer l'opération de débit, mais renvoi une erreur car l'opération n'est pas atomique (solde des contributeurs avant transaction != solde après erreur).

Est-ce qu'il faut réécrire la méthode debit dans GroupeDeContributeurs pour utiliser les transactions?

Merci d'avance,
Thomas

Joris_Oziol
Messages : 52
Inscription : 15 oct. 2016 13:59

Joris_Oziol

Message par Joris_Oziol » 02 déc. 2016 17:36

As tu passé les test de jnews ?
Si oui tu as ta réponse
Je pensais comme toi mais ce test met une erreur puisque comme tu l'as souligné non atomique ...

TSwank
Messages : 15
Inscription : 05 juin 2014 11:03

Re: TP Commit question 3

Message par TSwank » 02 déc. 2016 19:35

Effectivement, ça passe à l'envoi...

Merci pour ta réponse

gautierd
Messages : 49
Inscription : 12 oct. 2016 14:55

Re: TP Commit question 3

Message par gautierd » 03 déc. 2016 15:37

Bonjour,
Malgré de nombreux efforts, je n'arrive pas à mettre en place le memento et la transaction donc.
Je vois d'après le debogueur que je n'instancie pas l'état du memento quand il s'agit d'un groupe de cotisants.
Est-ce que quelqu'un voit une erreur dans le code de mes visiteurs, sachant que l'état de mon mémento est un simple Cotisant.
Merci d'avance.

Code : Tout sélectionner

private class VisiteurSauvegarde implements Visiteur<Cotisant> {
        public Contributeur visite(Contributeur cpt){
            return cpt;
        }

        public GroupeDeContributeurs visite(GroupeDeContributeurs grp){
            GroupeDeContributeurs res = new GroupeDeContributeurs(grp.nom());
            if (grp.nombreDeCotisants()>0) {
                List<Cotisant> liste = grp.getChildren();
                for (Cotisant c : liste)
                {
                    res.ajouter(c);
                }
            }
            return res;
        }
    }

    private class VisiteurRestitution implements Visiteur<Cotisant> {

        public Cotisant visite(Contributeur cpt){
            return mCotisant;
        }

        public Cotisant visite(GroupeDeContributeurs grp){
            GroupeDeContributeurs vGroupe = null;
            GroupeDeContributeurs relais = (GroupeDeContributeurs)mCotisant;
            if (vGroupe.nombreDeCotisants() > 0) {
                for (Cotisant c : relais.getChildren())
                {
                    vGroupe.ajouter(c);
                }
            }
            grp = vGroupe;
            return grp;
        }
    }

pellier
Messages : 37
Inscription : 30 oct. 2016 21:13

Re: TP Commit question 3

Message par pellier » 03 déc. 2016 16:58

Salut,

Dans VisiteurRestitution -> public Cotisant visite(GroupeDeContributeurs grp){
à quoi correspondent les 3 premières lignes ?

Code : Tout sélectionner

GroupeDeContributeurs vGroupe = null;
GroupeDeContributeurs relais = (GroupeDeContributeurs)mCotisant;
if (vGroupe.nombreDeCotisants() > 0) {
ligne 2 : Qu'est-ce que mCotisant ? il n'est pas définie dans cette méthode (ça passe à la compilation ?)
ligne 3 : à cet endroit vGroupe == null donc vGroupe.nombreDeCotisants() ne doit pas renvoyer grand chose

De même dans :

Code : Tout sélectionner

public Cotisant visite(Contributeur cpt){
            return mCotisant;
        }
Qu'est-ce que mCotisant ?

gautierd
Messages : 49
Inscription : 12 oct. 2016 14:55

Re: TP Commit question 3

Message par gautierd » 03 déc. 2016 17:06

Merci pour le retour. Mon code complet. Merci pour l'erreur notée.
Je cherche dans le visiteur reconstruction :
à relire la variable membre mCotisant (qui devrait contenir un groupe ou un contributeur) et à reconstruire un groupe vGroupe. Ce résultat doit être assigné au groupe visité grp donc je revoie grp = res.

Code : Tout sélectionner

package question3;

import question1.*;
import java.util.*;

public class Memento {
    // Note : Un usage du patron Memento, 
    //        d’un premier visiteur pour la sauvegarde et 
    //        d’un second pour la restitution du composite, 
    //        représentent une solution possible. 
    private Cotisant mCotisant;

    public Memento(Cotisant c) {
        mCotisant = c.accepter(new VisiteurSauvegarde());
    }

    public void setState(Cotisant c) {
        c = c.accepter(new VisiteurRestitution());
    }

    private class VisiteurSauvegarde implements Visiteur<Cotisant> {
        public Contributeur visite(Contributeur cpt){
            return cpt;
        }

        public GroupeDeContributeurs visite(GroupeDeContributeurs grp){
            GroupeDeContributeurs res = new GroupeDeContributeurs(grp.nom());
            if (grp.nombreDeCotisants()>0) {
                List<Cotisant> liste = grp.getChildren();
                for (Cotisant c : liste)
                {
                    res.ajouter(c);
                }
            }
            return res;
        }
    }

    private class VisiteurRestitution implements Visiteur<Cotisant> {

        public Cotisant visite(Contributeur cpt){
            return mCotisant;
        }

        public Cotisant visite(GroupeDeContributeurs grp){
            GroupeDeContributeurs vGroupe = null;
            GroupeDeContributeurs relais = (GroupeDeContributeurs)mCotisant;
            if (relais.nombreDeCotisants() > 0) {
                for (Cotisant c : relais.getChildren())
                {
                    vGroupe.ajouter(c);
                }
            }
            grp = vGroupe;
            return grp;
        }
    }

}

gautierd
Messages : 49
Inscription : 12 oct. 2016 14:55

Re: TP Commit question 3

Message par gautierd » 03 déc. 2016 17:08

mCotisant est bien l'état de mon composite que je cherche à sauvegarder.
encore merci

pellier
Messages : 37
Inscription : 30 oct. 2016 21:13

Re: TP Commit question 3

Message par pellier » 03 déc. 2016 17:39

Salut,

En fait j'ai l'impression que c'est la méthode que tu cherches à implémenter qui ne peut pas fonctionner.
J'ai peut-être mal compris mais :

Ton visiteurSauvegarde reconstruit un composite miroir de ton composite à sauvegarder et le stocke (en fait stocke l'adresse de sa racine) dans mCotisant.
Sauf que les Object composites (les feuilles et les groupes) de ton object miroir sont les mêmes Objects que ceux d'origine (pas des copies mais vraiment les mêmes) donc si tu modifies l'arbre initial tu modifies l'arbre sauvegardé.

Autrement dit :
- tu as un composite C avec une feuille <nom=a1 valeur=10> dans ce composite.
- tu sauvegardes ton composite ça te donne un composite sauvegarde C' avec une feuille <nom=a1 valeur=10>
- les feuilles a1 de C et a1 de C' sont un seul et même object
- donc si tu changes la valeur de (C,a1) cela modifie la valeur de (C',a1)

Donc ce système ne peut pas fonctionner pour effectuer une sauvegarde.
Mais la technique n'est pas loin de fonctionner si tu résous cette histoire.

gautierd
Messages : 49
Inscription : 12 oct. 2016 14:55

Re: TP Commit question 3

Message par gautierd » 03 déc. 2016 18:55

Ok.
Je saisis ta réponse. Mais alors comment créer une copie propre dans visiteur sauvegarde ?

Douin
Messages : 219
Inscription : 18 mars 2009 15:46

Re: TP Commit question 3

Message par Douin » 03 déc. 2016 19:34

Bonjour,

En hypothèse vous n'avez pas d'homonymes, donc une sauvegarde des soldes dans une "Map" générée par un visteur, puis une restitution selon le même principe devrait être une solution, il y en a d'autres ...

Bonne fin de question

gautierd
Messages : 49
Inscription : 12 oct. 2016 14:55

Re: TP Commit question 3

Message par gautierd » 03 déc. 2016 20:18

Merci pour vos retours.
Votre réponse Mr Douin laisse supposer (comme un autre post) qu'il faut utiliser les map.
Mais alors j'ai envie de dire, pourquoi ?
Mon idée est-elle possible et si oui qu'est ce qui ne va pas ?
Pourquoi alors utiliser une map ?

pellier
Messages : 37
Inscription : 30 oct. 2016 21:13

Re: TP Commit question 3

Message par pellier » 04 déc. 2016 16:21

Salut,

Je pense que si tu veux rester sur ton idée il faudrait modifier cette méthode :

Code : Tout sélectionner

public Contributeur visite(Contributeur cpt){
            return cpt;
        }
En la remplaçant le return par (dans l'idée) :
return new contributeur(cpt.nom , cpt.value)

Et du coup pour la restitution tu n'as même plus besoin de visiteur il te suffit de renvoyer ce composite créé.

Mais si Douin te suggère un map c'est peut-être plus sage…

XavierB
Messages : 24
Inscription : 14 oct. 2016 13:45

Re: TP Commit question 3

Message par XavierB » 06 déc. 2016 1:24

Bonsoir,

Je suis parti dans une solution similaire et mes tests sans transaction me retourne le bon solde...
Pourtant la classe de test m indiqué une erreur
après vérification j ai un solde = 360 avant rollback dans le setstate il passe à 600 et à la sortie j ai de nouveau un 360€...
J avoue que je tourne en rond...

J ai bien compris le principe du mémento et lappliquer me paraissait simple, force est de constater que je ne suis pas au point, je vais essayer autre chose...
Je verrai bien si je trouve ...
Bon courage à tous pour la fin.

Répondre

Qui est en ligne ?

Utilisateurs parcourant ce forum : Aucun utilisateur inscrit et 1 invité