JeuWeb - Crée ton jeu par navigateur
Valueobject - 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 : Valueobject (/showthread.php?tid=7392)

Pages : 1 2 3 4 5 6 7 8


RE: Valueobject - Xenos - 02-09-2015


Raison de la modification: oxman -> srm (mais pourquoi d'ailleurs ?)
Parce que Scala Rules! Mwahahahaha


Ok, j'vais rentrer chez moi


RE: Valueobject - niahoo - 02-09-2015

Non bah ça se tient. Je vois que ça. Tu as l'oeil alerte toi dis-moi Smile


RE: Valueobject - srm - 02-09-2015

(02-09-2015, 04:47 PM)niahoo a écrit : @Max72 ta classe value integer peut elle même étendre une classe abstraite. L'idée est de bloquer les setters et cela devrait se faire à un seul endroit.

@srm Tu as oublié de comparer les noms de ville en lowercase Smile

Enfin, les numéros de rue sont des String.

edit: les case class qui n'ont qu'un seul membre ont une fonction toString définie automatiquement qui output ce membre ?

En effet j'ai oublié le lowercase.
Pour les numéros de rue c'est un détail, j'ai respecté l'implémentation d'origine.

(02-09-2015, 04:54 PM)Xenos a écrit : @srm Ca compare quoi, le "==" en fin de ton Scala? Les valeurs des membres? Ou le résultat du toString?
Les valeurs des membres car j'ai utilisé des case class, donc ton test ne passe pas Wink

(02-09-2015, 04:54 PM)niahoo a écrit : srm ça compile pas ton truc
Oui normal je n'ai pas mis de main class, il suffit de le tester en faisant "scala nomdufichier.scala", ça fait l'équivalent d'un REPL avec un fichier.

Voilà l'exemple mis à jour par rapport à mon oubli :

import scala.reflect.ClassTag


abstract class CompareWithoutCase[T: ClassTag] {
    override def equals(that: Any) = that match {
        case that: T => this.toString equalsIgnoreCase that.toString
        case _ => false
    }
}

case class Numero(value: Int)  {
    require(value > 0, "Le numéro doit être positif")
}

case class Rue(value: String) extends CompareWithoutCase[Rue] {
    require(value.length > 0, "La rue ne doit pas être une chaîne vide")
}

case class Ville(value: String) extends CompareWithoutCase[Ville] {
    require(value.length > 0, "La ville ne doit pas être une chaîne vide")
}

case class Adresse(numero: Numero, rue: Rue, ville: Ville) {
    override def toString = numero.value + " " + rue.value + " " + ville.value
}

val adresse_de_jean   = Adresse(Numero(44), Rue("de la mairie"), Ville("Paris"))
val adresse_de_bob    = Adresse(Numero(44), Rue("de la Mairie"), Ville("PARIS"))
val adresse_dun_malin = Adresse(Numero(44), Rue("de la "), Ville("Mairie PARIS"))

println("Jean habite au " + adresse_de_jean);

if (adresse_de_bob == adresse_de_jean) {
    println("Adresses identiques pour Bob et Jean");
} else {
    println("Adresses différentes pour Bob et Jean");
}

if (adresse_de_bob == adresse_dun_malin) {
    println("Adresses identiques pour Bob et un malin");
} else {
    println("Adresses différentes pour Bob et un malin");
}

Jean habite au 44 de la mairie Paris

Adresses identiques pour Bob et Jean
Adresses différentes pour Bob et un malin


RE: Valueobject - srm - 02-09-2015

SRM parce que : Sylvain Robez-Masson


RE: Valueobject - niahoo - 02-09-2015

Pour les string je répondais à Max. Je me mélange un peu dans mes edit Smile

Hmmm ça te va mieux "oxman" !


RE: Valueobject - Max72 - 04-09-2015

J'y reviens !
Je me lance dans l'écriture d'un blog, avec mon premier article :
http://max-koder.com/2015/09/03/le-design-pattern-value-object/

Balancez vos critiques ! Smile


RE: Valueobject - Xenos - 04-09-2015

Mouais, je ne suis pas tant d'accord avec la notion de "Le value object est un simple objet où la comparaison n’est pas basée sur son identité." (faut-il que tous les attributs du value object soient égaux entre eux? Ou seulement certains?), ni celle d'"Un value object est un objet ‘immutable‘, c’est à dire qu’une fois créé, il ne sera plus possible de le modifier.": dans l'exemple du Personnage, pourquoi "Adresse" ne serait pas modifiable? Cela ne représente pas la maison à cette adresse (qui existe toujours), mais l'adresse du personnage?


Les 3 avantages présentées (vérifications internes à la classe, classes auto-explicite et type hinting) ne sont pas spécifiques aux Value Object, mais sont génériques à toute classe. En revanche, dire "Passer par des getter/setter permet de faire des checks qu'un attribut public ne permet pas", ce serait cohérent (surtout en PHP où les attributs ne sont pas typés, donc un attribut publique peut vraiment contenir n'importe quoi).


Citation :Remarquez l’implémentation de __toString pour pouvoir récupérer la valeur de l’objet sans getter, ça fait plus propre
Pas d'accord. Ok, ça peut servir pour faire de la concaténation de chaîne, mais si on veut la valeur réelle, on passe par le getter. Si on veut la valeur sous forme de chaine (qui pourrait donc inclure, par exemple, l'unité monétaire et dans certains pays celle(ci est avant le nombre façon $30), on passe par le __toString(). Les deux ont des portées différentes, et ne sont pas échangeables.


Pour le reste, l'article est bien écrit Smile



Ca m'a amené sur un autre article, Value Object vs Data Transfer Object.


RE: Valueobject - Max72 - 04-09-2015

Merci pour ta relecture et ton commentaire, j'apprécie.
Je vais essayer de te répondre point par point :

Citation :faut-il que tous les attributs du value object soient égaux entre eux? Ou seulement certains?)
Tous, ça me semblait logique.

Citation :Cela ne représente pas la maison à cette adresse (qui existe toujours), mais l'adresse du personnage?
En effet, c'est bien l'adresse du personnage. C'est (comme j'ai répondu sur le blog) la définition d'un Value Object, il est immutable. Si tu souhaites modifier l'adresse du personnage, tu en créé une nouvelle.

Citation :Les 3 avantages présentées (vérifications internes à la classe, classes auto-explicite et type hinting) ne sont pas spécifiques aux Value Object, mais sont génériques à toute classe
Tout à fait d'accord. Mais dans ma phrase, je met ces arguments face à l'utilisation de données simples (entiers, tableaux, ..), je ne parle pas d'autres classes ou patterns.

Citation :Pas d'accord. Ok, ça peut servir pour faire de la concaténation de chaîne, mais si on veut la valeur réelle, on passe par le getter.
C'est vrai, c'est une erreur de ma part, surtout dans le cas de nombre. Je vais ajouter une fonction getNative() qui permet la récupération de la donnée brute.

Citation :Pour le reste, l'article est bien écrit 2
Merci, j'ai pris conseil de vos remarques sur le moteur de templates Wink

Citation :Ca m'a amené sur un autre article, Value Object vs Data Transfer Object.
C'est marrant, parce que dans ton article, je cite :
Citation :A Value Object doesn't have any identity, it is entirely identified by its value and is immutable.
C'est la définition que j'en fais également, non ?

Enfin, je considère les DTO comme des simples conteneurs de données légers, sans vérification ni fioriture : On stocke la donnée, on la récupère ailleurs, point.

Merci Wink


RE: Valueobject - Ter Rowan - 04-09-2015

(04-09-2015, 05:30 PM)Xenos a écrit : dans l'exemple du Personnage, pourquoi "Adresse" ne serait pas modifiable? Cela ne représente pas la maison à cette adresse (qui existe toujours), mais l'adresse du personnage?


car une adresse, dans l'absolu, n'est pas intrinsèque au personnage. Une adresse est une position. Si le personnage change d'adresse l'adresse est toujours valide.
Dans les vrais modèles, tu as une table adresse et une table personnage et là tu as bien deux values objects : l'adresse, et le personnage


RE: Valueobject - Xenos - 04-09-2015

Egalité des attributs
Une question du coup: le ValueObject Temperature={0; °C} est-il égal au ValueObject Temperature={32, °F} ? Avec l'approche "attributs tous égaux", non. Avec l'approche logique "ça représente la même température", oui.
Ce qui gène en fait, c'est que "égalité des attributs" n'est pas un comportement externe, mais un fonctionnement interne. Peu importe le fonctionnement interne: deux ValueObject sont égaux s'ils représentent la même donnée vue de l'extérieur.

Mutable
Supposons un objet représentant un vecteur 3D (x,y,z). C'est mon value object. J'aimerai le doter de l'opérateur d'incrémentation vecteur++ qui aurait pour effet d'augmenter la longueur du vecteur de 1 (et donc, ses coordonées changent en conséquence). S'il est immutable, je ne peux pas le faire (alors que int++ existe). L'immutable limite un peu trop les choses à mon goût, mais il a l'avantage de limiter les comportements possibles de l'objet.


L'article VOvsDTO
Attention, car si effectivement l'article dit Un Value Object est défini par ses membres et est immutable ("A Value Object doesn't have any identity, it is entirely identified by its value and is immutable."), il précise aussi la définition du value objet: Un Value Object représente des données prédéfinies et peut s'assimiler à un Enum (A Value Object represents itself a fix set of data and is similar to a Java enum. A real world example would be Color.RED, Color.BLUE, SEX.FEMALE...").
Donc, Numero.BIS/.TER/.QUATER/QUINTER sont des ValueObject avec cette définition, et ils sont effectivement immutable (en tous cas pour moi). Mais l'adresse du joueur est-elle un Value Object au sens de cet article? Elle ressemble plus à un DTO pour moi, et là, c'est bien précisé que les setters y ont leur place (sous entendu, DTO est mutable).