(Typiquement, le listeneur connaît le générateur
directement, plus ou moins, tandis que le générateur ne connaît
les listeneurs que parce qu'ils s'y sont inscrits. C'est
peut-être ce que tu voulais dire, et que j'ai mal compris.)
je suis d'accord, et je l'ai mal exprimé.
ce que tu décris est le modèle habituel et en fait le PO reprends bien
ce modèle.
les exemples du PO, par ses noms de classes me faisait penser à une
retournement dans le sens où, j'imagine il y a ici plus de générateurs
que de listeneurs.
or, pour un schéma classique, on a souvent peu de générateurs (peu
d'instances d'une même classe) et possiblement de nombreux listeners,
d'où un classique "addListener" (public) fourni par le générateur.
dans le cas, où 1 ou 2 chasseurs / naturalistes écouteraient un groupe
de canards, j'aurais tendance à définir un "addObservable()" dans cette
classe listener - et cette méthode utiliserait un service ami du
générateur pour s'enregistrer, ceci donnant, imho, une meilleure vision
des priorités / responsabilités des agents.
(Typiquement, le listeneur connaît le générateur
directement, plus ou moins, tandis que le générateur ne connaît
les listeneurs que parce qu'ils s'y sont inscrits. C'est
peut-être ce que tu voulais dire, et que j'ai mal compris.)
je suis d'accord, et je l'ai mal exprimé.
ce que tu décris est le modèle habituel et en fait le PO reprends bien
ce modèle.
les exemples du PO, par ses noms de classes me faisait penser à une
retournement dans le sens où, j'imagine il y a ici plus de générateurs
que de listeneurs.
or, pour un schéma classique, on a souvent peu de générateurs (peu
d'instances d'une même classe) et possiblement de nombreux listeners,
d'où un classique "addListener" (public) fourni par le générateur.
dans le cas, où 1 ou 2 chasseurs / naturalistes écouteraient un groupe
de canards, j'aurais tendance à définir un "addObservable()" dans cette
classe listener - et cette méthode utiliserait un service ami du
générateur pour s'enregistrer, ceci donnant, imho, une meilleure vision
des priorités / responsabilités des agents.
(Typiquement, le listeneur connaît le générateur
directement, plus ou moins, tandis que le générateur ne connaît
les listeneurs que parce qu'ils s'y sont inscrits. C'est
peut-être ce que tu voulais dire, et que j'ai mal compris.)
je suis d'accord, et je l'ai mal exprimé.
ce que tu décris est le modèle habituel et en fait le PO reprends bien
ce modèle.
les exemples du PO, par ses noms de classes me faisait penser à une
retournement dans le sens où, j'imagine il y a ici plus de générateurs
que de listeneurs.
or, pour un schéma classique, on a souvent peu de générateurs (peu
d'instances d'une même classe) et possiblement de nombreux listeners,
d'où un classique "addListener" (public) fourni par le générateur.
dans le cas, où 1 ou 2 chasseurs / naturalistes écouteraient un groupe
de canards, j'aurais tendance à définir un "addObservable()" dans cette
classe listener - et cette méthode utiliserait un service ami du
générateur pour s'enregistrer, ceci donnant, imho, une meilleure vision
des priorités / responsabilités des agents.
"David Fleury" a écrit dans le message de news:
46aba941$0$10323$Je suis pas sur de comprendre. La solution générale ne consiste-t-elle
pas, justement, à se restreindre à l'interface IObservable ?
Dans ce cas, dans la mesure où restreindre l'interface me donne plus de
travail, j'assimile plus ça à une spécialisation. Une généralisation du
problème devrait me faire mon travailler.
Eun non. Te restreindre à l'interface IObservable, ça veut dire faire avec
l'existant sans rien ajouter.
"David Fleury" <dfleury2@libertysurf.fr> a écrit dans le message de news:
46aba941$0$10323$426a74cc@news.free.fr...
Je suis pas sur de comprendre. La solution générale ne consiste-t-elle
pas, justement, à se restreindre à l'interface IObservable ?
Dans ce cas, dans la mesure où restreindre l'interface me donne plus de
travail, j'assimile plus ça à une spécialisation. Une généralisation du
problème devrait me faire mon travailler.
Eun non. Te restreindre à l'interface IObservable, ça veut dire faire avec
l'existant sans rien ajouter.
"David Fleury" a écrit dans le message de news:
46aba941$0$10323$Je suis pas sur de comprendre. La solution générale ne consiste-t-elle
pas, justement, à se restreindre à l'interface IObservable ?
Dans ce cas, dans la mesure où restreindre l'interface me donne plus de
travail, j'assimile plus ça à une spécialisation. Une généralisation du
problème devrait me faire mon travailler.
Eun non. Te restreindre à l'interface IObservable, ça veut dire faire avec
l'existant sans rien ajouter.
oui mais sans répondre à mon problème. ;)
du coup je serais obligé dans ma fonction de faire des cast à tout va
pour identifier mon type d'Observable, et j'aimerai éviter ça si
possible ( d'où mes essais jusqu'ici infructueux avec les templates)
oui mais sans répondre à mon problème. ;)
du coup je serais obligé dans ma fonction de faire des cast à tout va
pour identifier mon type d'Observable, et j'aimerai éviter ça si
possible ( d'où mes essais jusqu'ici infructueux avec les templates)
oui mais sans répondre à mon problème. ;)
du coup je serais obligé dans ma fonction de faire des cast à tout va
pour identifier mon type d'Observable, et j'aimerai éviter ça si
possible ( d'où mes essais jusqu'ici infructueux avec les templates)
or, pour un schéma classique, on a souvent peu de générateurs (peu
d'instances d'une même classe) et possiblement de nombreux listeners,
d'où un classique "addListener" (public) fourni par le générateur.
Dans mon cas, j'aurais plutôt plusieurs type de générateurs (plusieurs
classes ) pour un type de listeneurs, une instance qui concentrerait les
résultat en quelque sort.
dans le cas, où 1 ou 2 chasseurs / naturalistes écouteraient un groupe
de canards, j'aurais tendance à définir un "addObservable()" dans
cette classe listener - et cette méthode utiliserait un service ami du
générateur pour s'enregistrer, ceci donnant, imho, une meilleure
vision des priorités / responsabilités des agents.
Là, je ne vois pas trop, mais je vais continuer à faire quelques essais
sur mon cas concret sans vouloir faire une solution trop générale qui
n'aurait qu'un intérêt que théorique pour moi.
or, pour un schéma classique, on a souvent peu de générateurs (peu
d'instances d'une même classe) et possiblement de nombreux listeners,
d'où un classique "addListener" (public) fourni par le générateur.
Dans mon cas, j'aurais plutôt plusieurs type de générateurs (plusieurs
classes ) pour un type de listeneurs, une instance qui concentrerait les
résultat en quelque sort.
dans le cas, où 1 ou 2 chasseurs / naturalistes écouteraient un groupe
de canards, j'aurais tendance à définir un "addObservable()" dans
cette classe listener - et cette méthode utiliserait un service ami du
générateur pour s'enregistrer, ceci donnant, imho, une meilleure
vision des priorités / responsabilités des agents.
Là, je ne vois pas trop, mais je vais continuer à faire quelques essais
sur mon cas concret sans vouloir faire une solution trop générale qui
n'aurait qu'un intérêt que théorique pour moi.
or, pour un schéma classique, on a souvent peu de générateurs (peu
d'instances d'une même classe) et possiblement de nombreux listeners,
d'où un classique "addListener" (public) fourni par le générateur.
Dans mon cas, j'aurais plutôt plusieurs type de générateurs (plusieurs
classes ) pour un type de listeneurs, une instance qui concentrerait les
résultat en quelque sort.
dans le cas, où 1 ou 2 chasseurs / naturalistes écouteraient un groupe
de canards, j'aurais tendance à définir un "addObservable()" dans
cette classe listener - et cette méthode utiliserait un service ami du
générateur pour s'enregistrer, ceci donnant, imho, une meilleure
vision des priorités / responsabilités des agents.
Là, je ne vois pas trop, mais je vais continuer à faire quelques essais
sur mon cas concret sans vouloir faire une solution trop générale qui
n'aurait qu'un intérêt que théorique pour moi.
David Fleury wrote on 28/07/2007 22:52:
oui mais sans répondre à mon problème. ;)
du coup je serais obligé dans ma fonction de faire des cast à tout va
pour identifier mon type d'Observable, et j'aimerai éviter ça si
possible ( d'où mes essais jusqu'ici infructueux avec les templates)
je ne comprends pas pourquoi vous souhaitez identifier (et pire caster)
le type d'observable !
pouvez-vous motiver ce point?
David Fleury wrote on 28/07/2007 22:52:
oui mais sans répondre à mon problème. ;)
du coup je serais obligé dans ma fonction de faire des cast à tout va
pour identifier mon type d'Observable, et j'aimerai éviter ça si
possible ( d'où mes essais jusqu'ici infructueux avec les templates)
je ne comprends pas pourquoi vous souhaitez identifier (et pire caster)
le type d'observable !
pouvez-vous motiver ce point?
David Fleury wrote on 28/07/2007 22:52:
oui mais sans répondre à mon problème. ;)
du coup je serais obligé dans ma fonction de faire des cast à tout va
pour identifier mon type d'Observable, et j'aimerai éviter ça si
possible ( d'où mes essais jusqu'ici infructueux avec les templates)
je ne comprends pas pourquoi vous souhaitez identifier (et pire caster)
le type d'observable !
pouvez-vous motiver ce point?
SI j'ai par exemple des capteurs différentes, par exemple
class Pression : public IObservable {
public: int getPression() const { return ... ; }
};
class Temperature : public IObservable {
public: int getTemperature() const { return ... ; }
};
Pour récupérer l'état de chacun des capteurs, je devrais utiliser une
méthode diférents (ou sinon peut être utiliser un Adapteur pour rendre
l'accès à l'état de mon Observable uniforme).
Alors qu'en castant, j'aurais directement l'interface (Pression ou
Temperature), donc accès directement à mes méthodes permettant
d'extraire tous les état de mes capteurs.
SI j'ai par exemple des capteurs différentes, par exemple
class Pression : public IObservable {
public: int getPression() const { return ... ; }
};
class Temperature : public IObservable {
public: int getTemperature() const { return ... ; }
};
Pour récupérer l'état de chacun des capteurs, je devrais utiliser une
méthode diférents (ou sinon peut être utiliser un Adapteur pour rendre
l'accès à l'état de mon Observable uniforme).
Alors qu'en castant, j'aurais directement l'interface (Pression ou
Temperature), donc accès directement à mes méthodes permettant
d'extraire tous les état de mes capteurs.
SI j'ai par exemple des capteurs différentes, par exemple
class Pression : public IObservable {
public: int getPression() const { return ... ; }
};
class Temperature : public IObservable {
public: int getTemperature() const { return ... ; }
};
Pour récupérer l'état de chacun des capteurs, je devrais utiliser une
méthode diférents (ou sinon peut être utiliser un Adapteur pour rendre
l'accès à l'état de mon Observable uniforme).
Alors qu'en castant, j'aurais directement l'interface (Pression ou
Temperature), donc accès directement à mes méthodes permettant
d'extraire tous les état de mes capteurs.
parmi les options possibles, IObservable ne concerne que la gestion de
la liste des listeners; les classes concrêtes devraient hériter de
manière protégée de cette classe et vous définirez comme actuellement
autant de méthode de notification qu'il existe de classe notifiante,
mais contrairement à votre PO vous auriez intérêt à mieux caractériser
les interfaces, par exemple à la place d'un unique IObserver, définir:
struct PressureListener {
virtual void notifyPressure(double value) = null;
};
struct TemperatureListener {
virtual void notifyTemperature(double value) = null;
};
struct Naturaliste : PressureListener, TemperatureListener {
....
};
Naturaliste implémentera n interfaces mais chacune sera claire et
immédiatement compréhensible - le fait de transmettre un paramètre
valeur (pour les mesures intensives ou extensibles) clarifira également
l'ensemble.
autre approche possible, si les évenement ssont assez simple, définir
une structure évenement commune, par exemple:
struct Event {
enum EventType {
TEMPERATURE,
PRESSURE,
...
};
EventType type;
double value;
[ when, why, ?, ... ]
// éventuellement, mais devrais être évité
// pour ne pas créer des dépendances inutiles
IObservable* source;
};
Observer est alors réduit à:
struct IObserver {
virtual void notify(Event&) = null;
};
ou, si event très simple:
struct IObserver {
virtual void notify(int /*ou enum*/ type, double value) = null;
};
et Naturaliste switchera, si besoin, sur le type de l'event.
cette façon de faire peut convenir si vous définissez un système où les
types d'évènements sont connus / fixés d'avance; elle sera par contre
pénalisante si le système gère des events de type très différents (pas
de struct Event simple) ou si ces types d'events peuvent évoluer dans la
vie du code (danger d'oublier un switch).Alors qu'en castant, j'aurais directement l'interface (Pression ou
Temperature), donc accès directement à mes méthodes permettant
d'extraire tous les état de mes capteurs.
certes, cependant lors de la génération d'un évènement distinct vous
disposez de toutes les informations: cet event est d'un type particulier
et est généré par une classe distincte; si on est obligé de caster la
source ou l'event lors de son traitement c'est que l'on a fait exprès de
perdre cette information (ou que l'on a oublié de la préserver); c'est
la raison pour laquelle je n'aimerais pas ce modèle.
l'observateur final ne peut pas / ne doit pas traiter une pression comme
un température, il fait donc sens (il n'est pas génant) d'avoir 2
interfaces distinctes pour recevoir ces 2 types d'events.
Sylvain.
parmi les options possibles, IObservable ne concerne que la gestion de
la liste des listeners; les classes concrêtes devraient hériter de
manière protégée de cette classe et vous définirez comme actuellement
autant de méthode de notification qu'il existe de classe notifiante,
mais contrairement à votre PO vous auriez intérêt à mieux caractériser
les interfaces, par exemple à la place d'un unique IObserver, définir:
struct PressureListener {
virtual void notifyPressure(double value) = null;
};
struct TemperatureListener {
virtual void notifyTemperature(double value) = null;
};
struct Naturaliste : PressureListener, TemperatureListener {
....
};
Naturaliste implémentera n interfaces mais chacune sera claire et
immédiatement compréhensible - le fait de transmettre un paramètre
valeur (pour les mesures intensives ou extensibles) clarifira également
l'ensemble.
autre approche possible, si les évenement ssont assez simple, définir
une structure évenement commune, par exemple:
struct Event {
enum EventType {
TEMPERATURE,
PRESSURE,
...
};
EventType type;
double value;
[ when, why, ?, ... ]
// éventuellement, mais devrais être évité
// pour ne pas créer des dépendances inutiles
IObservable* source;
};
Observer est alors réduit à:
struct IObserver {
virtual void notify(Event&) = null;
};
ou, si event très simple:
struct IObserver {
virtual void notify(int /*ou enum*/ type, double value) = null;
};
et Naturaliste switchera, si besoin, sur le type de l'event.
cette façon de faire peut convenir si vous définissez un système où les
types d'évènements sont connus / fixés d'avance; elle sera par contre
pénalisante si le système gère des events de type très différents (pas
de struct Event simple) ou si ces types d'events peuvent évoluer dans la
vie du code (danger d'oublier un switch).
Alors qu'en castant, j'aurais directement l'interface (Pression ou
Temperature), donc accès directement à mes méthodes permettant
d'extraire tous les état de mes capteurs.
certes, cependant lors de la génération d'un évènement distinct vous
disposez de toutes les informations: cet event est d'un type particulier
et est généré par une classe distincte; si on est obligé de caster la
source ou l'event lors de son traitement c'est que l'on a fait exprès de
perdre cette information (ou que l'on a oublié de la préserver); c'est
la raison pour laquelle je n'aimerais pas ce modèle.
l'observateur final ne peut pas / ne doit pas traiter une pression comme
un température, il fait donc sens (il n'est pas génant) d'avoir 2
interfaces distinctes pour recevoir ces 2 types d'events.
Sylvain.
parmi les options possibles, IObservable ne concerne que la gestion de
la liste des listeners; les classes concrêtes devraient hériter de
manière protégée de cette classe et vous définirez comme actuellement
autant de méthode de notification qu'il existe de classe notifiante,
mais contrairement à votre PO vous auriez intérêt à mieux caractériser
les interfaces, par exemple à la place d'un unique IObserver, définir:
struct PressureListener {
virtual void notifyPressure(double value) = null;
};
struct TemperatureListener {
virtual void notifyTemperature(double value) = null;
};
struct Naturaliste : PressureListener, TemperatureListener {
....
};
Naturaliste implémentera n interfaces mais chacune sera claire et
immédiatement compréhensible - le fait de transmettre un paramètre
valeur (pour les mesures intensives ou extensibles) clarifira également
l'ensemble.
autre approche possible, si les évenement ssont assez simple, définir
une structure évenement commune, par exemple:
struct Event {
enum EventType {
TEMPERATURE,
PRESSURE,
...
};
EventType type;
double value;
[ when, why, ?, ... ]
// éventuellement, mais devrais être évité
// pour ne pas créer des dépendances inutiles
IObservable* source;
};
Observer est alors réduit à:
struct IObserver {
virtual void notify(Event&) = null;
};
ou, si event très simple:
struct IObserver {
virtual void notify(int /*ou enum*/ type, double value) = null;
};
et Naturaliste switchera, si besoin, sur le type de l'event.
cette façon de faire peut convenir si vous définissez un système où les
types d'évènements sont connus / fixés d'avance; elle sera par contre
pénalisante si le système gère des events de type très différents (pas
de struct Event simple) ou si ces types d'events peuvent évoluer dans la
vie du code (danger d'oublier un switch).Alors qu'en castant, j'aurais directement l'interface (Pression ou
Temperature), donc accès directement à mes méthodes permettant
d'extraire tous les état de mes capteurs.
certes, cependant lors de la génération d'un évènement distinct vous
disposez de toutes les informations: cet event est d'un type particulier
et est généré par une classe distincte; si on est obligé de caster la
source ou l'event lors de son traitement c'est que l'on a fait exprès de
perdre cette information (ou que l'on a oublié de la préserver); c'est
la raison pour laquelle je n'aimerais pas ce modèle.
l'observateur final ne peut pas / ne doit pas traiter une pression comme
un température, il fait donc sens (il n'est pas génant) d'avoir 2
interfaces distinctes pour recevoir ces 2 types d'events.
Sylvain.
David Fleury wrote on 28/07/2007 22:52:
oui mais sans répondre à mon problème. ;)
du coup je serais obligé dans ma fonction de faire des cast à tout va
pour identifier mon type d'Observable, et j'aimerai éviter ça si
possible ( d'où mes essais jusqu'ici infructueux avec les templates)
je ne comprends pas pourquoi vous souhaitez identifier (et pire
caster) le type d'observable !
pouvez-vous motiver ce point?
SI j'ai par exemple des capteurs différentes, par exemple
class Pression : public IObservable {
public: int getPression() const { return ... ; }
...
};
et
class Temperature : public IObservable {
public: int getTemperature() const { return ... ; }
...
};
Pour récupérer l'état de chacun des capteurs, je devrais utiliser une
méthode diférents (ou sinon peut être utiliser un Adapteur pour rendre
l'accès à l'état de mon Observable uniforme).
Dans le cas où j'ai des accesseurs différents en nombre, je risque
d'avoir d'autres soucis.
Alors qu'en castant, j'aurais directement l'interface (Pression ou
Temperature), donc accès directement à mes méthodes permettant
d'extraire tous les état de mes capteurs.
David Fleury wrote on 28/07/2007 22:52:
oui mais sans répondre à mon problème. ;)
du coup je serais obligé dans ma fonction de faire des cast à tout va
pour identifier mon type d'Observable, et j'aimerai éviter ça si
possible ( d'où mes essais jusqu'ici infructueux avec les templates)
je ne comprends pas pourquoi vous souhaitez identifier (et pire
caster) le type d'observable !
pouvez-vous motiver ce point?
SI j'ai par exemple des capteurs différentes, par exemple
class Pression : public IObservable {
public: int getPression() const { return ... ; }
...
};
et
class Temperature : public IObservable {
public: int getTemperature() const { return ... ; }
...
};
Pour récupérer l'état de chacun des capteurs, je devrais utiliser une
méthode diférents (ou sinon peut être utiliser un Adapteur pour rendre
l'accès à l'état de mon Observable uniforme).
Dans le cas où j'ai des accesseurs différents en nombre, je risque
d'avoir d'autres soucis.
Alors qu'en castant, j'aurais directement l'interface (Pression ou
Temperature), donc accès directement à mes méthodes permettant
d'extraire tous les état de mes capteurs.
David Fleury wrote on 28/07/2007 22:52:
oui mais sans répondre à mon problème. ;)
du coup je serais obligé dans ma fonction de faire des cast à tout va
pour identifier mon type d'Observable, et j'aimerai éviter ça si
possible ( d'où mes essais jusqu'ici infructueux avec les templates)
je ne comprends pas pourquoi vous souhaitez identifier (et pire
caster) le type d'observable !
pouvez-vous motiver ce point?
SI j'ai par exemple des capteurs différentes, par exemple
class Pression : public IObservable {
public: int getPression() const { return ... ; }
...
};
et
class Temperature : public IObservable {
public: int getTemperature() const { return ... ; }
...
};
Pour récupérer l'état de chacun des capteurs, je devrais utiliser une
méthode diférents (ou sinon peut être utiliser un Adapteur pour rendre
l'accès à l'état de mon Observable uniforme).
Dans le cas où j'ai des accesseurs différents en nombre, je risque
d'avoir d'autres soucis.
Alors qu'en castant, j'aurais directement l'interface (Pression ou
Temperature), donc accès directement à mes méthodes permettant
d'extraire tous les état de mes capteurs.
[...]
Merci, c'est vraiment intéressant, je vais étudier plus en détail
tout ça.
parmi les options possibles, IObservable ne concerne que la gestion de
la liste des listeners; les classes concrêtes devraient hériter de
manière protégée de cette classe et vous définirez comme actuellement
autant de méthode de notification qu'il existe de classe notifiante,
mais contrairement à votre PO vous auriez intérêt à mieux caractériser
les interfaces, [snip]
Naturaliste implémentera n interfaces mais chacune sera claire et
immédiatement compréhensible - le fait de transmettre un paramètre
valeur (pour les mesures intensives ou extensibles) clarifira
également l'ensemble.
Je crois que ma préférence va à cette solution, les événements n'étant
pas simple et surtout potentiellement sans rapport.
autre approche possible, si les évenement ssont assez simple, définir
une structure évenement commune [snip]
et Naturaliste switchera, si besoin, sur le type de l'event.
[...]
Merci, c'est vraiment intéressant, je vais étudier plus en détail
tout ça.
parmi les options possibles, IObservable ne concerne que la gestion de
la liste des listeners; les classes concrêtes devraient hériter de
manière protégée de cette classe et vous définirez comme actuellement
autant de méthode de notification qu'il existe de classe notifiante,
mais contrairement à votre PO vous auriez intérêt à mieux caractériser
les interfaces, [snip]
Naturaliste implémentera n interfaces mais chacune sera claire et
immédiatement compréhensible - le fait de transmettre un paramètre
valeur (pour les mesures intensives ou extensibles) clarifira
également l'ensemble.
Je crois que ma préférence va à cette solution, les événements n'étant
pas simple et surtout potentiellement sans rapport.
autre approche possible, si les évenement ssont assez simple, définir
une structure évenement commune [snip]
et Naturaliste switchera, si besoin, sur le type de l'event.
[...]
Merci, c'est vraiment intéressant, je vais étudier plus en détail
tout ça.
parmi les options possibles, IObservable ne concerne que la gestion de
la liste des listeners; les classes concrêtes devraient hériter de
manière protégée de cette classe et vous définirez comme actuellement
autant de méthode de notification qu'il existe de classe notifiante,
mais contrairement à votre PO vous auriez intérêt à mieux caractériser
les interfaces, [snip]
Naturaliste implémentera n interfaces mais chacune sera claire et
immédiatement compréhensible - le fait de transmettre un paramètre
valeur (pour les mesures intensives ou extensibles) clarifira
également l'ensemble.
Je crois que ma préférence va à cette solution, les événements n'étant
pas simple et surtout potentiellement sans rapport.
autre approche possible, si les évenement ssont assez simple, définir
une structure évenement commune [snip]
et Naturaliste switchera, si besoin, sur le type de l'event.