OVH Cloud OVH Cloud

Serialisation et conception

8 réponses
Avatar
Kupee
Salut j'ai quelque problèmes de conception avec la sérialisation :

1er cas : imaginons que j'ai une classe Toto avec quelque champs
et une classe Tata extends Toto qui ajoute diverses fonctionnalités
Un serveur instantie des Tata, et le client arrive et veut qu'on lui
sérialise les Tata, mais pour récupérer des Toto (les fonctionnalités
supplémentaires ne l'intéressent pas) ya t'il un moyen de faire ca ?

2nd cas :
J'ai une classe Ville dans une Map, j'ai des Users qui on tous un champ
Ville avec dedans la ville ou ils habitent. Bien sur 2 utilisateurs
habitant la même ville ont la même instance de cette ville.
le client récupère d'abord toutes les Villes et les conserve en permanence.
Puis quand il demande les Users, j'aimerai par exemple ne sérialiser que
le nom de la ville puis le récupérer via la Map qui aura été récupérée
au préalable ...
Bien sur je peux le faire en lisant moi même directement sur le
ObjectInputStream mais j'aurai aimé pouvoir passer simplement par la
méthode readObject ...

merci

8 réponses

Avatar
dnasmars
Salut ,

Kupee wrote:
Salut j'ai quelque problèmes de conception avec la sérialisation :

1er cas : imaginons que j'ai une classe Toto avec quelque champs
et une classe Tata extends Toto qui ajoute diverses fonctionnalités
Un serveur instantie des Tata, et le client arrive et veut qu'on lui
sérialise les Tata, mais pour récupérer des Toto (les fonctionnalités
supplémentaires ne l'intéressent pas) ya t'il un moyen de faire ca ?
travail avec des interfaces.

en gros cela donnerais
toto implements interfaceToto
tata extends toto
une fois le travail de serialization effectué et que tu a recuperé
ton objet tu le cast avec l'interfaceToto et ton client n'aurras
que les methodes de toto.

j'espere que cela pourras t'aider

2nd cas :
J'ai une classe Ville dans une Map, j'ai des Users qui on tous un champ
Ville avec dedans la ville ou ils habitent. Bien sur 2 utilisateurs
habitant la même ville ont la même instance de cette ville.
le client récupère d'abord toutes les Villes et les conserve en permanence.
Puis quand il demande les Users, j'aimerai par exemple ne sérialiser que
le nom de la ville puis le récupérer via la Map qui aura été récupérée
au préalable ...
Bien sur je peux le faire en lisant moi même directement sur le
ObjectInputStream mais j'aurai aimé pouvoir passer simplement par la
méthode readObject ...
j'ai po compris :)


merci
a po de koi


Avatar
Kupee
dnasmars wrote:
Salut ,

Kupee wrote:
Salut j'ai quelque problèmes de conception avec la sérialisation :

1er cas : imaginons que j'ai une classe Toto avec quelque champs
et une classe Tata extends Toto qui ajoute diverses fonctionnalités
Un serveur instantie des Tata, et le client arrive et veut qu'on lui
sérialise les Tata, mais pour récupérer des Toto (les fonctionnalités
supplémentaires ne l'intéressent pas) ya t'il un moyen de faire ca ?
travail avec des interfaces.

en gros cela donnerais
toto implements interfaceToto
tata extends toto
une fois le travail de serialization effectué et que tu a recuperé
ton objet tu le cast avec l'interfaceToto et ton client n'aurras
que les methodes de toto.

j'espere que cela pourras t'aider


Malheureusement c'est plus compliqué que ca, l'objet Tata utilise en
plus des classes issu d'une librairie dont le client n'a pas besoin, et
donc le coup de l'interface ne serait pas satisfaisant car le client n'a
pas cette librairie ...


2nd cas :
J'ai une classe Ville dans une Map, j'ai des Users qui on tous un
champ Ville avec dedans la ville ou ils habitent. Bien sur 2
utilisateurs habitant la même ville ont la même instance de cette ville.
le client récupère d'abord toutes les Villes et les conserve en
permanence.
Puis quand il demande les Users, j'aimerai par exemple ne sérialiser
que le nom de la ville puis le récupérer via la Map qui aura été
récupérée au préalable ...
Bien sur je peux le faire en lisant moi même directement sur le
ObjectInputStream mais j'aurai aimé pouvoir passer simplement par la
méthode readObject ...
j'ai po compris :)



Eh bien j'ai a peu près ca :
public class Ville {
public String name;
public int nbHabitants;
public Ville(String name,int nbHabitants)
{
this.name = name;
this.nbHabitants = nbHabitants;
}
}


public class User {
private String name;
private Ville ville;
public User(String name, Ville ville) {
this.name = name;
this.ville = ville;
}
}

Les villes ne changent pas donc au début le client les récupère et fait
une map avec en clef le nom de la ville et en valeur l'objet Ville lui même.

Puis de temps en temps il récupère les users, sauf que je veux que les
User désérialisés n'aient pas leur propre instance de la ville mais
utilisent l'instance récupéré au début.
C'est proche de la fonctionnalité apportée par la méthode readResolve()
lors de la désérialisation mais malheureusement il faudrait que cette
méthode ait accès à la map des villes ce qui n'est pas le cas ...


Avatar
dnasmars
Kupee wrote:
dnasmars wrote:

Salut ,

Kupee wrote:

Salut j'ai quelque problèmes de conception avec la sérialisation :

1er cas : imaginons que j'ai une classe Toto avec quelque champs
et une classe Tata extends Toto qui ajoute diverses fonctionnalités
Un serveur instantie des Tata, et le client arrive et veut qu'on lui
sérialise les Tata, mais pour récupérer des Toto (les fonctionnalités
supplémentaires ne l'intéressent pas) ya t'il un moyen de faire ca ?


travail avec des interfaces.
en gros cela donnerais
toto implements interfaceToto
tata extends toto
une fois le travail de serialization effectué et que tu a recuperé
ton objet tu le cast avec l'interfaceToto et ton client n'aurras
que les methodes de toto.

j'espere que cela pourras t'aider



Malheureusement c'est plus compliqué que ca, l'objet Tata utilise en
plus des classes issu d'une librairie dont le client n'a pas besoin, et
donc le coup de l'interface ne serait pas satisfaisant car le client n'a
pas cette librairie ...

ok, il faudrait peut etre extraire les données dont le client

a besoin et ne serializer que ceux la ?

2nd cas :
J'ai une classe Ville dans une Map, j'ai des Users qui on tous un
champ Ville avec dedans la ville ou ils habitent. Bien sur 2
utilisateurs habitant la même ville ont la même instance de cette ville.
le client récupère d'abord toutes les Villes et les conserve en
permanence.
Puis quand il demande les Users, j'aimerai par exemple ne sérialiser
que le nom de la ville puis le récupérer via la Map qui aura été
récupérée au préalable ...
Bien sur je peux le faire en lisant moi même directement sur le
ObjectInputStream mais j'aurai aimé pouvoir passer simplement par la
méthode readObject ...


j'ai po compris :)



Eh bien j'ai a peu près ca :
public class Ville {
public String name;
public int nbHabitants;
public Ville(String name,int nbHabitants)
{
this.name = name;
this.nbHabitants = nbHabitants;
}
}


public class User {
private String name;
private Ville ville;
public User(String name, Ville ville) {
this.name = name;
this.ville = ville;
}
}

Les villes ne changent pas donc au début le client les récupère et fait
une map avec en clef le nom de la ville et en valeur l'objet Ville lui
même.

Puis de temps en temps il récupère les users, sauf que je veux que les
User désérialisés n'aient pas leur propre instance de la ville mais
utilisent l'instance récupéré au début.
C'est proche de la fonctionnalité apportée par la méthode readResolve()
lors de la désérialisation mais malheureusement il faudrait que cette
méthode ait accès à la map des villes ce qui n'est pas le cas ...
je ne sais quoi te proposer ...

sinon que "Premature optimization is the root of all evil"
voila



Avatar
obere
Salut,

Il y a une raison particuliere pour laquelle tu voudrais que ce soit
toujours la meme instance de l'objet ville qui soit utilisee ?
Avatar
obere
Salut,

Il y a une raison particuliere pour laquelle tu voudrais que ce soit
toujours la meme instance de l'objet ville qui soit utilisee ?
Avatar
Kupee
obere wrote:
Il y a une raison particuliere pour laquelle tu voudrais que ce soit
toujours la meme instance de l'objet ville qui soit utilisee ?


Plusieurs raisons oui, la première est que ces objets Ville yen a
quelque centaines, le client est appelé a partir de tomcat et les Villes
sont stockées dans l'application tomcat afin qu'elles soient partagées
entre tous les utilisateurs. Donc c'est une question de performances
réseau et mémoire principalement. Je ne passe que le nom de la ville et
hop je retrouve tous ses paramètres sans les avoir passé chaque fois sur
le réseau. Puis ayant plusieurs utilisateurs potentiels je risque de
multiplier ces objets redondants pour chacun d'entre eux.
a vrai dire pour l'instant j'ai dans mon objet Ville une méthode
serialize(ObjectOutput out)
et je les désérialise dans l'objet qui connait la Map, mais si cela
avait été possible j'aurai aimé passer par un truc standard
J'utilise déjà la méthode
readObject() pour les singletons et énumérations, ca marche bien mais je
n'ai pas trouvé comment l'utiliser dans mon cas particulier

Avatar
Hervé AGNOUX
Kupee wrote:


1er cas : imaginons que j'ai une classe Toto avec quelque champs
et une classe Tata extends Toto qui ajoute diverses fonctionnalités
Un serveur instantie des Tata, et le client arrive et veut qu'on lui
sérialise les Tata, mais pour récupérer des Toto (les fonctionnalités
supplémentaires ne l'intéressent pas) ya t'il un moyen de faire ca ?



Non. Tu peux faire diverses combines pour créer, à partir d'un Tata, un
Toto, mais de toutes façons tu serializes et déserializes un object Tata
complet.


2nd cas :
J'ai une classe Ville dans une Map, j'ai des Users qui on tous un champ
Ville avec dedans la ville ou ils habitent. Bien sur 2 utilisateurs
habitant la même ville ont la même instance de cette ville.
le client récupère d'abord toutes les Villes et les conserve en
permanence. Puis quand il demande les Users, j'aimerai par exemple ne
sérialiser que le nom de la ville puis le récupérer via la Map qui aura
été récupérée au préalable ...
Bien sur je peux le faire en lisant moi même directement sur le
ObjectInputStream mais j'aurai aimé pouvoir passer simplement par la
méthode readObject ...



Il faudrait que tu serializes Map et Villes dans le même flux.

Si, comme c'est probable, ce n'est pas possible, alors, au lieu de mémoriser
un objet Ville dans le Users, il faut que tu ne mémorises qu'un indicateur
de cette ville ; par exemple son numéro, son hashcode si tu garantis que
c'est le même quelque soit la machine virtuelle, ou tout ce que tu peux
imaginer qui puisse repérer une ville.


--
Hervé AGNOUX
http://www.diaam-informatique.com

Avatar
Olivier Thomann
Quoique tu fasses, définis le champ serialVersionUID dans toutes tes
classes qui peuvent être sérialisées.
--
Olivier