10
votes

Les objets efficacement immuables ont-ils un sens?

dans le livre Java Concurrence dans la pratique explique les avantages des objets "efficacement immuables" par rapport aux objets mutables de la concurrence . Mais cela n'explique pas quel avantage les objets "efficacement immutables" offriraient des objets immuables vraiment .

Et je ne comprends pas: tu ne peux pas toujours construire un objet vraiment immuable pour le moment que vous décideriez de publier en toute sécurité un objet "efficacement immuable"? (au lieu de faire votre "publication sûre", vous construirez un objet vraiment immuable et c'est tout)

Lorsque je concevons des cours, je ne vois pas les cas où je ne pouvais pas toujours construire un objet vraiment immuable (à l'aide de la délégation si nécessaire, etc. Pour construire d'autres objets emballés, elles-mêmes vraiment immoussables bien sûr) au moment où je voudrais décider de "publier en toute sécurité".

Ainsi sont un objet "efficacement immuable" et leur "publication sûre", juste un cas de mauvais design ou de mauvaises API?

Où seriez-vous obligé d'utiliser un objet efficacement immuable et d'être obligé de le publier en toute sécurité où vous ne pouviez pas construire un objet très élevé vraiment immuable?


0 commentaires

4 Réponses :


9
votes

Oui, ils ont du sens dans certains cas. Un exemple facile est que lorsque vous voulez que certaines propriétés soient générées paresseusement et mises en cache afin que vous puissiez éviter les frais généraux de la générer s'il n'est jamais accessible. String est un exemple de classe efficacement immuable qui le fait (avec son hachemode).


0 commentaires

1
votes

Utiliser efficacement des objets immuables vous permet d'éviter de créer un nombre considérable de classes. Au lieu de faire des paires de classes [de constructeur mutable] / [objet immuable], vous pouvez construire une classe efficacement immuable. Je définis généralement une interface immuable et une classe mutable implémente cette interface. Un objet est configuré via ses méthodes de classe mutable, puis publiées via son interface immuable. Tant que les clients de votre programme de bibliothèque à l'interface, vos objets restent immuables à travers leur durée de vie publiée.


1 commentaires

Un exemple de cette approche disponible?



3
votes

pour les immutables circulaires: xxx

une question est, car ceci de FOOA est divulgué à l'intérieur du constructeur, est FOOA toujours un fil de sécurité immuable? C'est-à-dire que si un autre thread lit foob.gether (). Param , est-il garanti de voir parama ? La réponse est oui, car ceci n'est pas divulgué à un autre fil avant le geler action; Nous pouvons établir des commandes HB / CC / MC requises par SPECT pour prouver que parama est la seule valeur visible de la lecture.

retour à votre question initiale. En pratique, il y a toujours des contraintes au-delà des purs techniques. Initialiser tout à l'intérieur du constructeur n'est pas nécessairement la meilleure option pour une conception, compte tenu de toutes les raisons d'ingénierie, opérationnelles, politiques et autres humaines.

se demandant pourquoi nous sommes nourris de penser que c'est une bonne idée suprême ?

Le problème plus profond est Java manque un fichier général bon marché pour une publication sûre qui est moins chère que volatile. Java n'a que pour Final champs; Pour une raison quelconque, cette clôture n'est pas disponible sinon.

maintenant final porte deux significations indépendantes: 1er, qu'un champ final doit être attribué exactement une fois; 2ème, la sémantique de la mémoire de la publication sûre. Ces deux significations n'ont rien à voir avec l'autre. Il est assez déroutant de les regrouper. Lorsque les gens ont besoin de la 2e signification, ils sont obligés d'accepter le 1er signification aussi. Lorsque le 1er est très gênant de réaliser dans une conception, les gens se demandent ce qu'ils ont mal fait - ne réalisant pas que c'est Java qui s'est trompé.

groupage de deux significations sous un final Le rend double plus bon, de sorte que nous avons apparemment plus de raison et de motivation à utiliser final . L'histoire plus sinistre est en fait, nous sommes obligés de l'utiliser car nous n'avons pas donné de choix plus flexible.


1 commentaires

+1 pour le grand exemple et l'explication. Aussi, je n'ai pas mentionné "final" mais c'est bien ce que nous devons utiliser ... En ce qui concerne les deux significations: il est encore plus déroutant vu que finale peut également être appliqué à des méthodes, mais je me digresse; ) J'aime l'exemple du constructeur bien que l'on puisse également le faire à l'aide d'une usine et / ou d'une interface fluide.



0
votes

Supposons que l'on a une classe immuable FOO avec cinq propriétés, nommée alpha , bêta , etc., et on souhaite fournir Withalpha , withbeta , etc. Méthodes qui retourneront une instance identique à l'original, sauf avec la propriété particulière modifiée. Si la classe est vraiment et profondément immuable, les méthodes doivent prendre la forme: xxx

ick. Une violation massive de «Ne vous répétez pas» (sèche)). En outre, l'ajout d'une nouvelle propriété à la classe nécessiterait de l'ajouter à chacune de ces méthodes.

d'autre part, si chaque foo a tenu un fooguts interne qui comprenait un constructeur de copie, on pourrait plutôt faire quelque chose comme: xxx

Le nombre de lignes de code de code pour chaque méthode a augmenté, mais les méthodes ne nécessitent plus besoin de Pour faire référence à toutes les propriétés, ils ne sont pas "intéressés". Notez que lorsqu'un FOO pourrait ne pas être immuable si son constructeur a été appelé avec un fooguts sur lequel Il existait de la référence extérieure, son constructeur n'est accessible qu'au code qui est de confiance à ne pas maintenir une telle référence après la construction.


0 commentaires