JeuWeb - Crée ton jeu par navigateur
[JS] Boucle for..in Array et ajout de methodes via prototype = conflit?! - 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 : [JS] Boucle for..in Array et ajout de methodes via prototype = conflit?! (/showthread.php?tid=7068)

Pages : 1 2 3 4 5 6 7 8 9 10 11


RE: [JS] Boucle for..in Array et ajout de methodes via prototype = conflit?! - Xenos - 03-08-2013

Oui, c'est vrai, j'ai pas fait gaffe pour l'unset.
Quand tu dis que ma bibliothèque gère "les livres et la traduction", je ne suis pas tout à fait d'accord. Pour moi, la bibliothèque gère le pack de Livres, dans sa globalité. Et le pack de livre peut être traduis (ce qui n'implique pas forcément la traduction de chaque livre). C'est pour cela que j'ai, dans cette bibliothèque, stocké des "propriétés" de livres et non les livres eux-mêmes: Ma Bibliothèque n'a pas vocation à être un conteneur de livre, mais à être l'objet "Ensemble de livres".
Quant à "forcément une porte de sortie", je demande à voir. S'il n'y a que des copies des propriétés qui sont envoyées vers ou depuis la classe, y'a pas de porte de sortie (évidemment, en considérant que je n'ai pas la possibilité de modifier le code de la classe).

Mon problème véritable n'est pas tant SOLID (je manque de pratique ok). Mon problème véritable, c'est la fuite d'informations qu'est l'envoi par une classe d'une référence à l'une de ses propriétés.

Par exemple, dans ce code
Code PHP :
<?php
define
('_YOUDOITRIGHT', false);

interface
Ifoo
{
public function
echoValeur();
public function
increment();
}
interface
Ibar
{
}

class
foo implements Ifoo
{
private
$valeur = 0;
public function
echoValeur()
{
echo(
'foo: ' . $this->valeur . '<br/>');
}
public function
increment()
{
$this->valeur++;
}
}

class
bar implements Ibar, Ifoo
{
private
$objet;

public function
__construct(Ifoo $p_obj)
{
if (
_YOUDOITRIGHT)
$this->objet = clone $p_obj;
else
$this->objet = $p_obj;
}
public function
echoValeur()
{
echo(
'bar: ');
$this->objet->echoValeur();
}
public function
increment()
{
echo(
'You cannot increment bar objet.<br/>');
}
}

class
Main
{
public static function
run()
{
$myFoo = new foo();
$myFoo->echoValeur();
$myFoo->increment();
$myFoo->echoValeur();

$myBar = new bar($myFoo);
$myBar->echoValeur();
$myBar->increment();
$myFoo->increment();
$myBar->echoValeur();
}
}
Main::run();

?>

Lorsque je l'exécute, j'obtiens (si je ne fais pas _YOUDOITRIGHT = true):
Citation :foo: 0
foo: 1
bar: foo: 1
You cannot increment bar objet.
bar: foo: 2

Et donc, dans ma classe "Main", j'ai accès à l'objet "foo", qui est une propriété "private" de "bar". Ne devrais-je pas avoir l'interdiction d'accéder à une propriété "private" ailleurs que dans sa propre classe?!


RE: [JS] Boucle for..in Array et ajout de methodes via prototype = conflit?! - srm - 03-08-2013

Et même si on ne parle pas du côté testable du code, les dépendances d'injection c'est utile dans la vie de tous les jours.

Si quelqu'un veut utiliser ta Bibliothèque il est obligé d'utiliser ton Storage, tu as pu choisir MySQL, des fichiers ou autre.
Si il veut autre chose il ne peut pas, il doit patcher ta Bibliothèque et à chaque mise à jour il doit la repatcher de nouveau.
Le truc super chiant au possible.

Moi si il veut un Storage sur le cloud avec Amazon, pas de soucis, il construit sa classe Storage qui respect le trait StorageLibrary, il l'injecte à la construction de la Bibliothèque et hop c'est terminé.

Par Reflection je peux récupérer toutes les données de ta classe que je veux et que tu cherches à cacher et m'empêcher de voir et je peux même modifier les propriétés en protected/private.

Si une Bibliothèque gère un pack de livre, un ensemble de livre. Elle va forcément avoir une liste de livre.
Pas une liste de titre, de contenu, d'auteurs, etc. Ca n'est pas question de point de vue, c'est question de programmation objet.
Si ta Bibliothèque n'a pas de liste de livre, tu décides de stocker les données en procédurale et pas en objet.
C'est un choix, mais tu fais à la fois de la POO et de la procédurale de façon... Inapproprié.

En quoi ça te gêne la fuite d'information ?
C'est pas une fuite, une fuite c'est quand ça arrive à l'utilisateur, pas au programmeur, pas au programme.

Tu n'accèdes pas à la propriété privé tu accèdes à increment qui est une méthode publique qui choisit comment modifier la valeur privé.

Que tu ne sois pas d'accord quand je dis que ta Bibliothèque n'est pas Single Responsability, si tu veux, mais tu te trompes.
Gérer une Bibliothèque : 1 responsabilité
Stocker la Bibliothèque : 1 autre responsabilité
Traduire la Bibliothèque : 1 autre responsabilité


RE: [JS] Boucle for..in Array et ajout de methodes via prototype = conflit?! - Xenos - 03-08-2013

D'accord, effectivement, mon "Storage" est ici forcé. Ok, S O L I et D me vont tous les 5 dans le principe. Mais alors, quand le site dit "pas de mot clef new dans la class", cela ne concerne bel et bien pas "clone": je n'utilise pas directement l'objet qui m'est envoyé, mais j'en fais une copie et j'utilise cette copie dans ma classe?

Citation :Elle va forcément avoir une liste de livre.
Je croyais qu'on ne se préoccupais justement pas du "comment" c'est stocké. Si ma bibliothèque traite l'ensemble, on n'a pas à présupposer de comment les éléments de l'ensemble sont stockés.

Il me semble plutôt que l'utilisateur de ma classe "bar" sont toutes les classes ou autres "bouts de code" qui vont... "utiliser" un objet de cette classe. Donc, l'utilisateur serait ma classe "Main". Si bar et foo étaient dans un package, l'utilisateur du package serait Main. Sinon, à quoi cela servirait-il d'utiliser "public/protected/private"? Là, j'ai un private visible du dehors de la classe, ça fait désordre...

Pour Reflection, peux-tu me montrer comment tu fais pour:
- Lire une variable private (type de base, ou objet)
- Modifier la variable private (type de base ou objet)

j'ai accès à "MyFoo", donc à la propriété private de bar :heu:

Et c'est pour cela que je demandais la différence précise entre "Gérer" et "Faire". Pour moi, "Gérer la Bibliothèque", ok, c'est 1 responsabilité et 1 classe. Mais "Traduire la bibliothèque", c'est 1 action, c'est 1 "faire", donc une méthode. As-tu un genre de "grille" qui permettrait de dire "tel truc est 1 responsabilité" ou "tel truc est un faire"?


RE: [JS] Boucle for..in Array et ajout de methodes via prototype = conflit?! - BAK - 03-08-2013

Xenos, ce qui te gène, ce sont les effets de bord. La POO ne spécifie pas qu'elle ne doit pas en avoir, même s'il est évident qu'ajouter plus d'effets de bord (en l’occurrence plus de références) dans un programme le rend plus compliqué, moins lisible.

Ils sont généralement acceptés et sont très utile si utilisé à bon escient. Pour palier aux inconvénients des références, on a inventé pas mal de principe pour limiter les risques. En C++, on a les pointeurs intelligents, le RAII, ou encore des systèmes de verrou.


Un bon principe (je ne connais pas son nom) est qu'un objet ne devrait avoir qu'un seul propriétaire.
Garder cette notion en tête permet de limiter les effets de bord, mais ne les interdit pas. En l’occurrence, la bibliothèque autorise l'utilisateur à modifier le livre, uniquement dans la fonction de callback. Le code utilisateur a accès au livre, mais n'en est pas "propriétaire". Il n'as donc pas à supprimer le livre, ni a en garder une référence.

Si tu veut absolument éviter les effets de bord, tu devrait te tourner du coté des langages fonctionnelles.


RE: [JS] Boucle for..in Array et ajout de methodes via prototype = conflit?! - Xenos - 03-08-2013

D'accord, ok, c'est donc bien ça! J'aurai donc du attendre 10 ans avant qu'on m'explique enfin le vrai soucis des "effets de bord" XD Merci !
(et oui, j'adore les langages fonctionnels, justement pour ça :p)

Donc, ok, SOLID je suis d'accord avec le principe (même si j'ai encore du mal à l'appliquer), et on est d'accord que les effets de bord, ça doit être bien gérés (donc, à chaque des dev, et non du langage).

Conclusion de tout cela: Gaffe avec les "Array.forEach(callback)" qui peut poser de gros soucis s'il est utilisé par un développeur inconnu ou incompétent, à cause des effets de bord possible (ça vous va?)

J'ai l'impression d'avoir plus appris en 2 jours et 10 pages sur jeuWeb qu'en 1 an de cours avec un certain prof...

Merci à vous trois d'avoir pris le temps, Niahoo, Oxman (désolé d'avoir été un peu raide à 2h du matin dans l'un des posts), et BAK.
Et désolé à Argorate d'avoir "un peu" dérivé ton topic :p

Et plus par curiosité qu'autre chose: comment décririez-vous l'effet du mot clef "Private" pour rendre explicite cette notion d'effet de bord? La définition
Citation :private : seule la classe peut accéder à la propriété/méthode.
me semble problématique du fait de ces effets de bord (enfin définis clairement avec un exemple concret et non bateau!)


RE: [JS] Boucle for..in Array et ajout de methodes via prototype = conflit?! - srm - 03-08-2013

Ce que j'expliquais pour Bibliothèque et le stockage d'objet Livre n'a rien à voir avec le principe SOLID.
Mais de la logique pure de programmation, tu travailles avec des objets, ta Bibliothèque permet de gérer/stocker des objets Livre.
Donc tu stocks des objets Livres et non pas des titres, des contenus.

Pour Reflection je t'invite plutôt à chercher et trouver ça toi même, ça va te permettre de voir toutes les possibilités de la Reflection.
J'ai géré des effets de bord dans mon code Scala ?
Pas vraiment non, ça pose problème ? Non.

Pas vraiment d'accord sur ta conclusion, c'est de la programmation basique. Et il n'y a pas vraiment d'effet de bord possible plus ici qu'ailleurs.

Concernant les responsabilités, non, c'est une réflexion et une logique.
Si je suis bibliothécaire et que je gère une bibliothèque, je m'occupe pour simplifier de l'entrer et la sortie des livres.
Ce sont les étagères qui sont responsables de stocker les livres, qu'ils ne tombent pas, etc.
Et si je venais à traduire les livres, ça ne serait pas de ma responsabilité en tant que bibliothécaire, mais de celle d'un traducteur.


RE: [JS] Boucle for..in Array et ajout de methodes via prototype = conflit?! - Xenos - 03-08-2013

J'ai essayé...
Code PHP :
<?php
class A
{
private
$var = 'SecretVar';
}

$secret = new a();
$reflector = new ReflectionClass('A');
$properties = $reflector->getProperties();
foreach(
$properties as $property)
{
var_dump($property);
var_dump($secret->{$property->getName()});
}
?>
Mais à part me prendre un "Fatal error: Cannot access private property A::$var", cela n'est pas concluant...

Citation :Si je suis bibliothécaire et que je gère une bibliothèque
Ok, le Bibliothécaire gère le rangement des livres. Mais on parle ici de la Bibliothèque, pas du Bibliotécaire...


Re: [JS] Boucle for..in Array et ajout de methodes via prototype = conflit?! - srm - 03-08-2013

Une bibliothèque est un lieu où est stocké des livres.

Pour la Reflection cherche encore.


RE: [JS] Boucle for..in Array et ajout de methodes via prototype = conflit?! - Xenos - 03-08-2013

Je croyais que c'était l'armoire qui stockait... Bon, admettons, c'est un point de vue de concepteur alors (ou il existe des règles?! Il ne me semble pas).

Pour Reflection, ok avec setAccessible. Mais il s'agit quand même d'une vulnérabilité. Donc, oui, on pourra aller éditer les propriétés private, mais entre
Code PHP :
<?php 
$secret
= new a();
$obj = new A();
$refObject = new ReflectionObject( $obj );
$refProperty = $refObject->getProperty('vars');
$refProperty->setAccessible(true);
$refProperty->setValue($secret, 'Not secret');
$secret->get();
et
Code PHP :
<?php 
$myFoo
= new foo();
$myBar = new bar($myFoo);
$myFoo->increment();

je trouve qu'il y a un écart ("trouve", donc pas une règle absolue).
Alors, ok, on peut pas empêcher la malveillance (enfin, avec "--disable-reflection", cela semble possible). Mais on peut empêcher l'erreur. La sécurité porte à la fois contre les malveillants et contre les étourdis; n'en contrer que la moitié, c'est déjà un bon début.


RE: [JS] Boucle for..in Array et ajout de methodes via prototype = conflit?! - niahoo - 04-08-2013

faite gaffe quand vous faites du dropping: Open/closed, Single Responsibility, ...

Quand même, quand je regarde les codes PHP et Erlang, je trouve qu'en 10 lignes je suis plus simple que 40 interfaces pour faire la même chose. Bon je n'ai pas mis la méthode de traduction dans un module livre, cette interface rajoutant 2-3 lignes.

Si tu veux donner la possibilité aux livres de stocker le nom de leur auteur ta classe bibliothèque va devoir être réimplémentée, c'est moche. Je suis curieux de savoir desquels tu parles quand tu dis adorer les langages fonctionnels.

Et sinon je suis (encore) d'accord avec oxman, la POO à été faite pour calquer les programmes sur des objets réels (ce dont je ne suis pas fan) mais ce sont plutot les maisons d'édition qui traduisent les bouquins, pas les bibliothèques.