Bonjour � tous,
Supposons que je code une API de ce type :
Utilis�e de cette mani�re :
Code : S�lectionner tout - Visualiser dans une fen�tre � part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 //classe abstraite class ServiceResource { static ServiceResource* Create(); static void Destroy(ServiceResource* res); protected: ~ServiceResource(); } //classe abstraite class Service { static Service* Create(); static void Destroy(Service* res); virtual void connect(ServiceResource* res) = 0; protected: ~Service(); }
J'aimerais qu'� l'appel de ServiceResource::Destroy(res), l'objet srv qui utilise cette ressource s'en "d�sabonne", par un syst�me de callbacks ou autre.
Code : S�lectionner tout - Visualiser dans une fen�tre � part
1
2
3
4
5
6
7
8
9
10
11
12
13 // Allocation Service* srv = Service::Create(); ServiceResource* res = ServiceResource::Create(); // Acquisition de la ressource par le service srv->connect(res); // Utilisation du service ... // Désalloc ServiceResource::Destroy(res); Service::Destroy(srv);
Pour l'instant je proc�de ainsi, ServiceImpl et ServiceResourceImpl �tant les deux classes concr�tes impl�mentant mon API :
Mes classes concr�tes disposent donc de pointeurs en attributs (et des get/set associ�s) pour se d�signer l'un l'autre, de mani�re � ce que le service connaisse l'adresse de la ressource et inversement.
Code : S�lectionner tout - Visualiser dans une fen�tre � part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 void ServiceImpl::connect(ServiceResource* res) { ServiceResourceImpl* resimpl = dynamic_cast<ServiceResourceImpl*>(res); if (resimpl != nullptr) { // Pour que la ressource sache quel service l'utilise, et puisse notifier le service pour qu'il s'en désabonne si la ressource est détruite // (nb: idéalement il faudrait remplir un pool de services, pour gérer le cas d'abonnements multiples à une ressource, mais passons) resimpl->setService(this); } this->resource = res; } void ServiceResource::Destroy(ServiceResource* res) { ServiceResourceImpl* resimpl = dynamic_cast<ServiceResourceImpl*>(res); if (resimpl != nullptr) { // "nullptr" pour que le service comprenne qu'il n'est plus connecté à aucune ressource. resimpl->getService()->connect(nullptr); } delete res; }
Mais comme vous avez pu le remarquer, j'utilise des dynamic_cast, donc RTTI, ce que j'aimerais �viter. Connaissez-vous une solution alternative, un design pattern que j'aurais manqu� ?
Contraintes :
- Pas de types STD/BOOST dans le header de mon API ; en fait je n'y inclus rien.
- Si possible, ne pas trop polluer les classes de l'API. L'abonnement doit �tre transparent pour l'utilisateur (quoique, si vous avez un avis diff�rent sur ce dernier point, je vous �coute).
Partager