Question

Dans la section sur « Good Encapsulation » dans le code complet, il est recommandé de cacher les détails de mise en œuvre privée. Un exemple est donné en C ++. L'idée est essentiellement de séparer complètement l'interface de la mise en œuvre, même dans le niveau de la classe.

class Employee {
public:
    ...
    Employee( ... );
    ...

    FullName GetName() const;
    String GetAddress() const;

private:
    EmployeeImplementation *m_implementation;
};

Est-ce vraiment une bonne utilisation du temps? Non seulement cela semble inefficace (quel genre de sanctions de performance cela donnerait?), mais toute la devise du code complet ( « gestion de la complexité ») semble avoir été reversed- le fait pas ajouter complexité?

Était-ce utile?

La solution

Un autre avantage de l'idiome PIMPL peut être à maintenir la ABI . Voir Le Pimpl Idiom dans la pratique .

Taille de la classe reste constante. Cela signifie que vous pouvez changer la mise en œuvre interne, tout en gardant l'interface intacte.

Si la mise en œuvre est distribuée sous forme compilée (lib, dll, donc, etc.), puis, sous certaines conditions, vous pourriez être en mesure de remplacer simplement la bibliothèque sans avoir à recompiler le code qui utilise la classe. Ainsi, vous découpler le code en tant que module complètement autonome, tant que l'interface publique ne change pas.

Comme d'autres l'ont dit, il réduit également le temps de compilation, qui peut être assez de raison, dans certains cas.

Autres conseils

Eh bien, il fait l'encapsulation d'augmentation depuis votre fichier d'en-tête ne contient plus que les membres du public et un seul pointeur vers une implémentation privée.

Il a aussi (un peu?) Réduit la performance en raison du niveau d'indirection supplémentaire.

Le "réduit le temps de compilation" est la question clé ici.

Si vous (votre entreprise) sont les seuls utilisateurs de la classe alors je ne pense pas que vous avez des raisons d'utiliser cet idiome. Vous obtenez des performances plus bas et vous devriez avoir tous les jours (ou périodique) reconstitue de votre code source de toute façon (ce qui devrait être au courant des dépendances entre les classes).

Cela signifie que le temps de compilation devrait être largement hors de propos si vous êtes le seul consommateur de la classe.

Si vous distribuez la bibliothèque alors l'histoire est complètement différente. Les changements dans les en-têtes signifient tous les clients que vous avez aura besoin pour reconstruire leurs applications pour utiliser votre nouvelle version, même si ce que vous avez fait était de changer les parties intimes de la classe. En utilisant l'idiome Pimpl ici signifierait le changement est invisible pour les utilisateurs de votre bibliothèque dynamique.

Un niveau supplémentaire d'indirection par pointeur peut causer des défauts de cache supplémentaires et ralentir votre programme. Autant que je sache, cet idiome (PIMPL) est le plus souvent suggéré de réduire le temps de compilation. Disons que vous avez un en-tête de employee.h ayant avec tous les champs de la classe, au lieu d'un seul pointeur. Maintenant, chaque fois que vous modifier les détails des employés (par exemple ajouter ou supprimer des champs), y compris tous les fichiers que employee.h doit être recompilé. Si tout ce que vous avez est un pointeur vers une classe d'implémentation définie dans employee.cpp, alors seulement employee.cpp doit être recompilé lorsque vous changez EmployeeImplementation.

, est la réduction de la valeur de la compilation, le coût supplémentaire? Vous seul pouvez décider.

Je pense que le principal avantage (ou au moins d'entre eux) de l'idiome Pimpl n'est pas un gain de temps de compilation, mais permettant lâche couplage , à savoir la rupture des dépendances entre les composants.

Supposons que vous fournissez une bibliothèque d'infrastructure qui utilisent beaucoup d'autres composants. Puis, comme @zvrba indiqué, chaque fois que vous changez votre implémentation privée détaille tous vos clients doivent recompiler. Il pourrait être pas une grosse affaire, mais dans de grands projets complexes une intégration entre les composants peut être une tâche complexe. Avec Pimpl, si votre bibliothèque est dynamique (dll, .so), aucune action est requise par vos clients.

Cet idiome est utilisé pour abstraire sur les en-têtes pauvres, et pas grand-chose. Utilisez uniquement si les types requis pour définir la classe implique notamment les en-têtes qui fuient les macros, prendre beaucoup de temps pour compiler, etc. En dehors de cela, il est généralement pas considéré comme la bonne chose à faire. Étant donné que votre mise en œuvre nécessite une allocation dynamique et la sémantique de référence de toute façon, vous pouvez tout aussi bien faire une interface et d'offrir une méthode de CreateForMyPlatform() qui a une définition dans un fichier cpp. Au moins, vous pouvez utiliser des pointeurs intelligents pour ce scénario.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top