Salut,
C'est avec plaisir que je donne les quelques informations que j'ai.
C'est vrai, mais c'est un peu court.
Ceci en revanche n'est pas vrai. Si tu conçoit bien ta fonction Clone, tu peux tout à fait faire cela. Heureusement, sinon, il n'y aurait aucun intérêt à utiliser la factory.
Voici des indices pour te mettre sur la piste : oublions la factory pour le moment et concentrons nous sur les décorateurs. Si tu construit un objet "archer" de la manière dont tu l'as proposé :
et qu'ensuite, tu fais appel à la fonction, par exempleCode:
1
2
3
4
5 WarElement * aWarElement2 = new WarElement(100, 15); // Points of life 100, Power 15 aWarElement2 = new DecoratorArc(*aWarElement2, 200, 100); //Points of life upgrade 200 / Power 60 aWarElement2 = new DecoratorUpgradable(*aWarElement2); aWarElement2->lifeUp(0.2); //+20% life up aWarElement2->powerUp(0.3); //+30% power up
Tu t'attend à ce qu'il se produise la chose suivante :Code:aWarElement2.getLife()
-> la fonction int DecoratorUpgradable::getLife() est exécutée
-> elle appelle la fonction int DecoratorArc::getLife()-> DecoratorUpgradable::getLife() ajoute 30% au résultat et le renvoie
-> celle-ci appelle la fonction int WarElement::getLife() qui renvoie 100-> DecoratorArc::getLife() n'ajoute rien au résultat et se contente de le renvoyer
Je suppose que tu as bien compris que chaque fonction d'un décorateur que tu redéfinis est obligée d'appeler la fonction équivalent de l'objet de base.
Imaginons par exemple que le fait de posséder l'arc fasse perdre deux points de vie à tes unités (par exemple, pour représenter la force qu'elles dépensent à l'utiliser).
Si tu as définis ta fonctioncomme ceci :Code:int DecoratorUpgradable::getLife()
et que tu définis ta fonctionCode:
1
2
3
4 int DecoratorUpgradable::getLife() { return m_Base.m_Life*m_coefficientUpgrade; }
comme ceci :Code:int DecoratorArc::getLife()
et bien ton programme ne marchera pas : quand tu appellerasCode:
1
2
3
4 int DecoratorArc::getLife() { return m_Base.m_Life-2; }
, il se produira la chose suivante :Code:aWarElement2.getLife()
-> la fonction int DecoratorUpgradable::getLife() est exécutée
-> elle n'appelle la fonction int DecoratorArc::getLife() elle renvoie directement m_Base (c'est à dire 100) -2, (c'est à dire 98)
Ce n'est pas ce que tu veux, ce que tu veux, c'est définir tes fonctions comme ceci :
etCode:
1
2
3
4 int DecoratorUpgradable::getLife() { return m_Base.getLife()*m_coefficientUpgrade; }
Ainsi tu auras exactement le comportement voulu etCode:
1
2
3
4 int DecoratorArc::getLife() { return m_m_Base.getLife()-2; }
CODE]aWarElement2.getLife()[/CODE] te renverra bien 100*1.3-2 = 128.
Je suppose que tu as parfaitement bien compris ceci.
Et bien maintenant il ne te reste plus qu'à appliquer le même raisonnement à la fonction.Code:Clone()
Une fois que ceci sera fait, c'est à dire une fois que le code suivant fonctionnera :
Ce ne sera plus très dur d'introduire la Factory et de faire fonctionner le code que tu proposes plus haut.Code:
1
2
3
4
5
6
7
8
9
10
11
12 ... WarElement * aWarElement2 = new WarElement(100, 15); // Points of life 100, Power 15 aWarElement2 = new DecoratorArc(*aWarElement2, 200, 100); //Points of life upgrade 200 / Power 60 aWarElement2 = new DecoratorUpgradable(*aWarElement2); aWarElement2->lifeUp(0.2); //+20% life up aWarElement2->powerUp(0.3); //+30% power up WarElement * aWarElement1 = aWarElement2.Clone(); std::cout<<"Points of life of aWarElement1 before attack " <<aWarElement1 ->getTotalPointsOfLife()<<std::endl; aWarElement2->attack(aWarElement1 ); std::cout<<"Points of life of aWarElement1 after attack " <<aWarElement1 ->getTotalPointsOfLife()<<std::endl;