JeuWeb - Crée ton jeu par navigateur
Compass : East Oriented - Version imprimable

+- JeuWeb - Crée ton jeu par navigateur (https://jeuweb.org)
+-- Forum : Discussions, Aide, Ressources... (https://jeuweb.org/forumdisplay.php?fid=38)
+--- Forum : Programmation, infrastructure (https://jeuweb.org/forumdisplay.php?fid=51)
+--- Sujet : Compass : East Oriented (/showthread.php?tid=7165)

Pages : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30


RE: Compass : East Oriented - srm - 04-06-2015

Tu mets quel instanceof justement ?
Tu ne le sais pas.
Du coup ça veut dire quoi ? Pour coder ta classe tu dois connaitre le monde extérieur.
Donc que quelque chose en dehors de ta classe peut faire planter ta classe.
Ca ne te choque pas ?


RE: Compass : East Oriented - srm - 04-06-2015

Ta boite noire on ne sait pas comment elle fonctionne ni ce qu'elle peut faire du coup comment le programme peut interagir avec elle ?


RE: Compass : East Oriented - srm - 04-06-2015

La documentation ne doit pas être obligatoire pour pouvoir utiliser une classe. Tu dois pouvoir l'utiliser sans documentation, sinon il y a vraiment un problème.


RE: Compass : East Oriented - Xenos - 04-06-2015

Les instanceof dépendent de la logique interne de la méthode hello(). Si cette classe ne veut dire hello() qu'aux filles (oui, bon, ben c'est la condition qui m'est venue à l'esprit devant la TV XD), elle fera son petit $data instanceof Fille en interne.
Pour coder ma classe, je dois effectivement connaitre une chose du monde extérieur: que $data est une variable du langage. C'est tout. Instanceof, c'est une fonction qui interroge cette variable, et qui n'est qu'un genre de "getter" (plutôt un checker).

Ma boite noire, on sait juste qu'elle répond à la méthode hello(mixed $data). Comment elle y répond, c'est un soucis interne.

Je suis d'accord, mais le nom de méthode que tu as choisis n'est pas explicite. C'est au nom de méthode de te dire ce que fait la méthode. Comment elle le fait (à coup d'instanceof ici), c'est son problème interne.

Tu peux reprendre l'exemple simplifié précédent du Barman, le coder en East, et ensuite ajouter la religion? Juste pour pouvoir comparer la quantité de modifications que East va impliquer. Sinon, si tu peux expliciter, comme j'avais demandé, en quoi ajouter des classes et interfaces comme précédemment casserait tout sans que je ne le vois au travers d'un exemple de code, je suis preneur.


RE: Compass : East Oriented - Jade H - 04-06-2015

J'ai lu toute la conversation, ce qui m'a permis de comprendre que je possède un niveau si bas, que je crois que je vais faire mon institut de massage, je pense que c'est un bon plan de carrière. LoL

En tout cas c'est intéressant merci pour le débat Smile


RE: Compass : East Oriented - srm - 04-06-2015

Pour toi donc c'est mieux de faire :

class Conan
{
public askGold($object)
{
if ($object instanceof Beggar) {
$object->giveGold($this->gold/2);
}

if ($object instanceof Kid) {
$object->giveGold($this->gold);
}
}
}

Que de faire ça :

class Conan
{
public askGoldByBeggar(Beggar $beggar)
{
$beggar->giveGold($this->gold/2);
}

public askGoldByKid(Kid $kid)
{
$kid->giveGold($this->gold);
}
}

C'est ça ? Si oui pourquoi ?


RE: Compass : East Oriented - Xenos - 05-06-2015

C'est cela.
Je distingue clairement le typage acceptable par une méthode (typehinting) et le typage qui permet à l'algo de réagir différemment (instanceof). Dans ton cas (le 2nd), le typage acceptable et le typage de l'algo sont les mêmes.


Pour moi, c'est mieux, par réutilisabilité et pour le principe de l'open/close, plus d'autres raisons satellites :

La réutilisabilité est favorisée car il n'existe qu'une seule méthode askGold (qui peut d'ailleurs être typée, par exemple par l'interface Player ou n'importe quelle autre jugée utile): on centralise l'algorithme en un seul endroit (une méthode), et cela évite de répéter du code

L'open/close car si d'autres discriminations de ce asker sont à ajouter, elles n'impacteront que le code interne de la méthode: aucun changement de classe ni d'interface n'est requis, et aucun impact n'a lieu dans le reste du code (tant que le changement d'algorithme n'impacte pas la doc). On peut même faire ces changements sans toucher au contenu de la méthode existante (s'il est trop complexe, cf l'exemple où elle passe en private).

Si je n'ai pas besoin, dans mon algo, de différencier Kid et Beggar, la 2nde solution oblige quand même à faire 2 méthodes

• On centralise l'algorithme en un seul lieu: on évite de répéter du code (cf les deux propositions plus bas).

• On peut faire des combinaisons internes: que faire dans le 2nd cas si le demandeur est à la fois un Kid et un Beggar? Il faut ajouter une nouvelle interface? Mais si j'ai 4 types possibles (Kid, Beggar, Stanger, Seller) combinables, il va falloir... 16 interfaces supplémentaires ?!

• Il est du ressort de l'appelé (une seule classe) de faire le tri entre ceux qui demandent de l'or, c'est plus facile à maintenir que de devoir faire le tri au niveau des appelants (multiples, voir même dans d'autres projets).

• Comment faire, dans la 2nd solution, si la classe appelée décide de ne plus réagir différemment pour un typage donné (Beggar)? On garde la méthode Beggar? Ce sera la même que celle de Kid... On la supprime? On casse le code utilisateur.

• On garde la possibilité de bluffer la classe appelée: l'appelant peut lui passer un $object qui est un KidProxy, pour se faire passer pour un Kid


D'ailleurs, j'aurai surement synthétisé de cette façon (en pratique, j'aurai surement fait un return, mais bon):
Code PHP :
<?php 
class Conan
{
public
askGold($object)
{
$factor = $object instanceof Beggar ? 0.5 : $object instanceof Kid ? 1 : null;
if (
$factor != null)
$object->giveGold($this->gold * $factor);
}
}

En return (West):
Code PHP :
<?php 
class Conan
{
/**
* Allows $object to ask how much gold Conan has.
* @param $object Who's asking (Conan may lie depending on the asker).
*/
public askGold($object)
{
return
$object instanceof Beggar ? $this->gold/2. : $object instanceof Kid ? $this->gold : null;
}
}


Note que pour moi, ces deux méthodes (tes deux exemples) n'ont pas forcément de lien avec East.
Pour moi, East, c'est clairement return $this;, point et c'est pas pratique et mal venu.
Là, c'est une discussion pour savoir s'il vaut mieux faire N méthodes avec un typehinting précis (typage de l'algorithme) ou 1 méthode avec un typehinting large, et laisser l'algorithme faire du instanceof.


RE: Compass : East Oriented - srm - 05-06-2015

Ok je continue mon explication, si je fais ça :

interface Hero
{
public function askGold($object);
}

interface Beggar
{
public function meetHero(Hero $hero);
}

class Conan implements Hero
{
public askGold($object)
{
if ($object instanceof Beggar) {
$object->giveGold($this->gold/2);
}

if ($object instanceof Kid) {
$object->giveGold($this->gold);
}
}
}

class FrancoisdAssise implements Beggar
{

public function meetHero(Hero $hero)
{
$hero->askGold($this);
}

}

$conan = new Conan();
$francoisdAssise = new FrancoisdAssise();
$francoisdAssise->meetHero($conan);

Est-ce que tu vois un problème se profiler ?


RE: Compass : East Oriented - srm - 05-06-2015

Tu vas voir au fur et à mesure que mon exemple se complique pourquoi il ne faut pas faire du instanceof.
Ça n'est pas directement lié à l'East mais c'est une des recommandations et tu vas comprendre pourquoi.

Et East non c'est pas juste "return $this" .
C'est un ensemble de pratique dont la plus marquante est "toujours return $this sur les méthodes publiques"


RE: Compass : East Oriented - niahoo - 05-06-2015

Il est pas bon ton exemple. On est censé faire des type hinting d'interfaces, pas de classes. Or Beggar est une classe, pas une interface.