Java Popsicle Immuable


Je travaille sur un problème où je dois charger un grand nombre d'entrées dans un problème et traiter ces entrées pour créer un "espace problème" (c'est-à-dire construire des structures de données permettant un accès efficace aux entrées, etc.). Une fois cette initialisation terminée, un processus multithread démarre qui utilise largement les entrées organisées/traitées de manière simultanée.

Pour des raisons de performances, je ne veux pas verrouiller et synchroniser toutes les opérations de lecture dans la phase simultanée. Ce que je veux vraiment, c'est un objet immuable, sûr d'accès par plusieurs lecteurs simultanément.

Pour des raisons pratiques (lisibilité et maintenabilité), je ne veux pas faire de InputManager un véritable objet immuable (c'est-à-dire tous les champs 'final' et initialisés dans la construction). Le InputManager aura de nombreuses structures de données (listes et cartes), où les objets dans chacun ont de nombreuses références circulaires les uns aux autres. Ces objets sont construits comme de "vrais" objets immuables. Je n'ai pas vous voulez avoir un constructeur à 14 arguments pour InputManager, mais j'ai besoin de la classe InputManager pour fournir une vue cohérente en lecture seule de l'espace problème une fois construit.

Ce que je vais chercher, c'est "l'immutabilité de popsicle" comme discuté par Eric Lippert ici.

L'approche que j'adopte repose sur l'utilisation de la "visibilité des paquets" de toutes les méthodes de mutation et l'exécution de toutes les actions mutables (c'est-à-dire la construction du InputManager) dans un seul paquet. Getters ont tous visibilité publique.

Quelque Chose comme:

public final class InputManager {  // final to prevent making mutable subclasses 
    InputManager() { ... } //package visibility limits who can create one
        HashMap<String,InputA> lookupTable1;
        ...

    mutatingMethodA(InputA[] inputA) { //default (package visibility)
        //setting up data structures...
    }

    mutatingMethodB(InputB[] inputB) { //default (package visibility)
        //setting up data structures...
    }

    public InputA getSpecificInput(String param1) {
        ... //access data structures
        return objA; //return immutable object
    }
}

L'idée globale, si je n'ai pas été assez claire, est que je construirai le InputManager dans un seul thread, puis le transmettrai à plusieurs threads qui effectueront un travail simultané en utilisant l'objet. Je veux appliquer ce cycle de vie d'objet mutable/immuable "en deux phases" aussi bien que possible, sans faire quelque chose de trop "mignon". Vous cherchez des commentaires ou des commentaires sur de meilleures façons d'atteindre cet objectif, car je suis sûr que ce n'est pas une utilisation rare mais je ne trouve pas non plus de modèle de conception qui le supporte.

Merci.

Author: BrianV, 2012-10-24

3 answers

Personnellement, je resterais avec votre approche simple et suffisante, mais au cas où vous seriez intéressé, il y a une chose comme un compagnon mutable idiome. Vous écrivez une classe interne qui a des mutateurs, tout en réutilisant tous les champs et les getters de l'instance englobante.

Dès que vous perdez le compagnon mutable, l'instance englobante qu'il laisse derrière lui est vraiment immuable.

 1
Author: Marko Topolnik, 2012-10-24 19:05:07

Je pense que vous pouvez simplement avoir des interfaces séparées pour vos deux phases. L'un pour la partie bâtiment, l'autre pour la partie lecture. De cette façon, vous séparez proprement vos modèles d'accès. Vous pouvez voir cela comme une instance du principe de ségrégation d'interface (pdf):

Les clients ne doivent pas être obligés de dépendre d'interfaces qu'ils n'utilisent pas.

 1
Author: Jordão, 2012-10-24 18:20:36

Tant que l'objet est publié en toute sécurité et que les lecteurs ne peuvent pas le muter.

" Publication " signifie ici comment le créateur met l'objet à la disposition des lecteurs. Par exemple, le créateur l'a placé dans une file d'attente de blocage et les lecteurs interrogent la file d'attente.

Cela dépend de votre méthode de publication. Je parie qu'il est sécuritaire.

 1
Author: irreputable, 2012-10-24 18:34:58