Question

La classe suivante:

class Pizza {

    Ingredients ingredients;
    Price price;

    public setIngredients(Ingredients ing) {
        if (ingredients != null) {
            throw new IllegalStateException();
        }
        ingredients = ing;
        return this;
    }

    public setPrice(Price p) {
        if (price != null) {
            throw new IllegalStateException();
        }
        price = p;
        return this;
    }

}

pourrait être utilisé dans un modèle de constructeur, et après il a été construit, il est efficacement immuable , parce que chaque propriété peut être définie qu'une seule fois. C'est:

Pizza pizza = new Pizza().setIngredients(something).setPrice(somethingelse);

Cependant, Pizza est pas sûre: il n'y a aucune garantie que le fil B voit les ingrédients qui ont été mis en elle par le fil A. Il existe des moyens pour y remédier:

  • final membres. Mais vous ne pouvez pas utiliser un modèle de constructeur.
  • Synchronize l'accès aux membres. Mais cela semble comme les déchets, parce qu'ils sont écrits qu'une seule fois jamais.
  • Faites-les volatile. Considère que les déchets, comme la synchronisation.
  • Utilisez AtomicReference.
  • Etc.

Ma question est, quelle est la meilleure façon de dire la machine virtuelle Java qu'un membre de la classe ne changera pas après une certaine méthode a été appelée? Dois-je simplement synchroniser l'accès à, et la confiance que la machine virtuelle Java optimisera loin la serrure? Il se sent juste déchets, parce que je sais que l'élément devrait se comporte comme elle est final après sa série. Y a-t-il pas de meilleures solutions?

Était-ce utile?

La solution

modèle Builder signifie généralement que le constructeur est un objet distinct. Dans ce cas, vous pouvez faire des champs de l'objet en cours de construction final, et les initialiser dans le constructeur appelé par l'objet constructeur:

Pizza pizza = 
    new PizzaBuilder()
        .setIngredients(something)
        .setPrice(somethingelse)
        .build(); 

Vous pouvez vous assurer en toute sécurité la publication de l'objet Pizza. Notez que les idiomes de publication de sécurité sont appliquées au champ qui contient une référence à l'objet en cours de publication, de ne pas les champs de cet objet lui-même. Par exemple, si pizza est un champ d'un objet, vous pouvez le rendre volatile ou un accès synchronisent -. Il assurerait la publication en toute sécurité objet Pizza attribué à ce champ

Autres conseils

Si les valeurs membres ne sont jamais destinées à changer, le meilleur modèle serait d'avoir un constructeur de Pizza qui prend comme paramètres Ingredients et Price, et ne pas avoir des méthodes de réglage sur l'objet du tout. Vraiment il n'est pas utile d'avoir une méthode setSomething() qui lance une exception après la première fois qu'il est appelé.

Considérons le fonctionnement de la classe String. Une fois que vous avez instancié un String avec un texte, la valeur de texte ne peut pas être modifié. La seule façon d'obtenir un String avec une valeur différente est de construire une nouvelle. Il semble que c'est ce que vous voulez ici.

L'utilisation de ce modèle permet également d'éviter le problème de synchronisation.

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