2009-05-21 4 views
0

Je me rends compte que je vais flamber pour ne pas simplement écrire un test moi-même ... mais je suis curieux de connaître l'opinion des gens, pas seulement la fonctionnalité, alors ... voilà ...Puis-je ajouter à une liste privée directement via le getter?

J'ai une classe qui a une liste privée. Je veux ajouter à cette liste privée à travers la méthode publique getMyList().

alors ... cela fonctionnera-t-il?

public class ObA{ 
private List<String> foo; 
public List<String> getFoo(){return foo;} 
} 

public class ObB{ 
    public void dealWithObAFoo(ObA obA){ 
    obA.getFoo().add("hello"); 

    } 
} 

Répondre

4

Oui, cela fonctionnera tout à fait - ce qui est généralement une mauvaise chose. (En effet, vous renvoyez réellement une référence à l'objet de collection, et non une copie de la collection elle-même.)

Très souvent, vous souhaitez fournir un accès en lecture seule à une collection, ce qui signifie généralement le retour un wrapper en lecture seule autour de la collection. Faire du type de retour une interface en lecture seule implémentée par la collection et renvoyer la référence de collection réelle ne fournit pas beaucoup de protection: l'appelant peut facilement convertir le type de collection "réel" et ensuite ajouter sans aucun problème.

+0

merci Jon. Dans mon scénario, ObA est un DTO, j'ajoute à l'un de ses membres à travers une classe de service ... Que suggéreriez-vous est l'approche préférée, en supposant que je veux garder le DTO aussi libre que possible du comportement (sens, je J'aimerais être fondamentalement un détenteur de données factice qui n'a pas de logique métier à l'intérieur). –

+0

euh ... Je voulais dire que je voudrais * que ce soit ...Je crains personnellement que je n'ai pas le choix en tant que détenteur de données fictives :) –

+0

Si c'est vraiment * un * être un cours "stupide", et tous ses clients sauront * que * la collection peut très bien être modifié par d'autres appelants, alors c'est correct d'aller avec comme il est. Je documenterais ceci très explicitement - quelque chose comme: "Cette propriété renvoie une référence directe à la collection de sauvegarde: toutes les modifications apportées via cette référence seront vues par les autres appelants." –

2

En effet, ce n'est pas une bonne idée. Ne publiez pas vos membres mutables à l'extérieur, faites une copie si vous ne pouvez pas fournir une lecture seule version à la volée ...

public class ObA{ 
    private List<String> foo; 
    public List<String> getFoo(){return Collections.unmodifiableList(foo);} 
    public void addString(String value) { foo.add(value); } 
} 
+0

J'aime cette approche. Merci! –

+0

Je pense que cela dépend vraiment - je serais normalement d'accord, mais parfois je trouve qu'il est logique d'avoir des DTO vraiment stupides qui n'essaient pas vraiment de faire beaucoup d'encapsulation. –

+0

Même dans le cas de DTO, autant que possible. Comme l'a dit Joshua Bloch (ou Brian Goetz?), À moins qu'il n'y ait vraiment une très bonne raison de ne pas rendre l'objet immuable. Bien sûr, un cas particulier est l'objet Java Bean, qui a des setters et des getters ... mais à part ça ... essayer de rendre chaque objet immuable ou fournir des méthodes pour effectuer la mutabilité (vous devez avoir un contrôle total dessus). –

1

Si vous voulez une opinion sur le faire, je supprimer l'appel et getFoo() ajouter une add(String msg) et remove(String msg) méthodes (ou toute autre fonctionnalité que vous souhaitez exposer) à ObA

+0

Adrian vous a battu au punch avec cette réponse, mais je vous donne un vote de toute façon, puisque vous ne saviez pas ce qui se passait que vous étiez en train de taper :) –

+0

Bien sûr, vous pouvez également ajouter ObA.remove (String value) ou toute autre méthode désirée pour manipuler foo ... –

1

Donner accès à la collection semble toujours être une mauvaise chose dans mon expérience - principalement parce qu'ils sont pratiquement impossibles à contrôler une fois qu'ils sortent . J'ai pris l'habitude de ne jamais permettre un accès direct aux collections en dehors de la classe qui les contient. Le raisonnement principal derrière ceci est qu'il y a presque toujours une sorte de logique métier attachée à la collecte de données - par exemple, validation en plus ou peut-être un jour vous aurez besoin d'ajouter une deuxième collection étroitement liée .

Si vous autorisez l'accès comme vous parlez, il sera très difficile à l'avenir de faire une modification comme celle-ci. Oh, aussi, je trouve souvent que je dois éventuellement stocker un peu plus de données avec l'objet que je stocke - donc je crée un nouvel objet (seulement connu dans le "Container" qui contient la collection) et J'ai mis l'objet dedans avant de le mettre dans la collection.

Si vous avez gardé votre collection verrouillée, c'est un refactor trivial. Essayez d'imaginer à quel point ce serait difficile dans certains cas où vous n'avez pas gardé la collection verrouillée ...

1

Si vous vouliez ajouter et supprimer des fonctions à Foo, je suggérerais les méthodes addFoo() et removeFoo(). Idéalement, vous pouvez éliminer ensemble le getFoo en créant une méthode pour chaque fonctionnalité dont vous avez besoin. Cela permet de clarifier les fonctions qu'un appelant va préformer sur la liste.

Questions connexes