152 votes

Hibernate Annotations - ce Qui est mieux, un champ ou l'accès à la propriété?

Cette question est liée en quelque sorte à http://stackoverflow.com/questions/305880/hibernate-annotation-placement-question.

Mais je veux savoir ce qui est mieux? L'accès via les propriétés ou l'accès via les champs? Quels sont les avantages et les inconvénients de chacune?

261voto

Martin Points 1121

Il existe des arguments pour les deux, mais la plupart d'entre eux proviennent de certaines exigences de l'utilisateur "que faire si vous devez ajouter de la logique", ou "xxxx pauses encapsulation". Cependant, personne n'a commenté sur la théorie, et donné un correctement l'argumentation raisonnée.

Qu'est-ce que Hibernate/JPA, en train de faire quand il persiste un objet - eh bien, c'est la persistance de l'ÉTAT de l'objet. Cela signifie que de les stocker dans une manière qu'il peut être facilement reproduit.

Qu'est-ce que l'encapsulation? Dispositifs d'encapsulation des moyens de l'encapsulation des données (ou d'état) avec une interface de l'application/client peut utiliser pour accéder aux données en toute sécurité - homogénéité et valide.

Pensez à cela comme MS Word. MS Word maintient un modèle de document dans la mémoire les documents de l'ÉTAT. Il présente une interface qui permet à l'utilisateur de modifier le document - un ensemble de boutons, les outils, les raccourcis clavier, etc. Toutefois, lorsque vous choisissez de persister (Enregistrer) ce document, il enregistre l'état interne, et non l'ensemble des combinaisons de touches et de clics de souris utilisé pour les générer.

Économiser de l'état interne de l'objet NE peut PAS briser l'encapsulation - sinon vous ne comprenez pas vraiment ce que l'encapsulation signifie, et pourquoi il existe. Il est juste comme objet de la sérialisation vraiment.

Pour cette raison, DANS la PLUPART des CAS, il convient de conserver les CHAMPS et pas les ACCESSEURS. Cela signifie qu'un objet peut être fidèlement recréé à partir de la base de données exactement de la manière dont il a été stocké. Il ne devrait pas avoir besoin de validation, parce que cela a été fait sur l'original quand il a été créé, et avant il a été stocké dans la base de données (sauf si, à Dieu ne plaise, vous êtes le stockage de données non valides dans la DB!!!!). De même, il devrait y avoir aucun besoin de calculer des valeurs, comme ils ont déjà été calculées avant que l'objet a été stocké. L'objet doit regarder juste comme il l'a fait avant, il a été sauvé. En fait, en ajoutant d'autres trucs dans les getters/setters vous sont effectivement augmenter le risque de recréer quelque chose qui n'est pas une copie exacte de l'original.

Bien sûr, cette fonctionnalité a été ajoutée pour une raison. Il peut être valide des cas d'utilisation pour la persistance de la accesseurs, cependant, ils seront généralement rares. Un exemple peut être que vous voulez éviter la persistance d'une valeur calculée, bien que vous pourriez vouloir poser la question de savoir pourquoi vous n'avez pas à calculer sur la demande dans la valeur du getter, ou paresseusement l'initialiser dans la lecture. Personnellement, je ne vois pas de bon de cas d'utilisation, et aucune des réponses ici donne vraiment un "Génie Logiciel" réponse.

86voto

duffymo Points 188155

Je préfère d'accès sur le terrain, parce que de cette façon je ne suis pas obligé de fournir des getter/setter pour chaque propriété.

Une enquête rapide via Google suggère que l'accès aux champs est la majorité (par exemple, http://java.dzone.com/tips/12-feb-jpa-20-why-accesstype).

Je crois que le terrain est le langage recommandé par le Printemps, mais je ne peux pas trouver une référence à dos.

Il y a une relative DONC, la question qu'a tenté de mesurer la performance et est venu à la conclusion qu'il n'y a "pas de différence".

40voto

HDave Points 6943

Voici une situation où vous devez utiliser les accesseurs de propriété. Imaginez que vous avez un GÉNÉRIQUE classe abstraite avec beaucoup de mise en œuvre de la bonté d'hériter en 8 sous-classes concrètes:

public abstract class Foo<T extends Bar> {

    T oneThing;
    T anotherThing;

    // getters and setters ommited for brevity

    // Lots and lots of implementation regarding oneThing and anotherThing here
 }

Maintenant exactement comment annoter cette classe? La réponse est que VOUS ne POUVEZ PAS l'annoter avec tous les deux sur le terrain ou de l'accès à la propriété parce que vous ne pouvez pas spécifier l'entité cible à ce point. Vous devez annoter le des implémentations concrètes. Mais depuis le persisté propriétés sont déclarées dans cette super-classe, vous DEVEZ utilisé l'accès à la propriété dans les sous-classes.

Accès sur le terrain n'est pas une option, dans une application à abstraite générique super-classes.

33voto

Pascal Thivent Points 295221

J'ai tendance à préférer et à utiliser les accesseurs de propriété:

  • Je peux ajouter de la logique, si le besoin s'en fait sentir (comme mentionné dans l'acceptation de réponse).
  • il me permet de faire appel foo.getId() sans initialisation d'un proxy (important lors de l'utilisation d'Hibernate, jusqu'à ce que HHH-3718 résolu).

Inconvénient:

  • elle rend le code moins lisible, vous avez par exemple pour parcourir l'ensemble de la classe pour voir si il y a @Transient autour de là.

32voto

Miguel Ping Points 9013

Je préfère les accesseurs, depuis que je peux ajouter un peu de logique métier à mes accesseurs chaque fois que j'ai besoin. Voici un exemple:

@Entity
public class Person {

  @Column("nickName")
  public String getNickName(){
     if(this.name != null) return generateFunnyNick(this.name);
     else return "John Doe";
  }
}

En outre, si vous lancez une autre libs dans le mélange (à l'instar de certains JSON de conversion de lib ou BeanMapper ou de Terrassement ou d'autres bean cartographie/clonage lib basé sur les propriétés de lecture/définition), vous aurez la garantie que la lib est en phase avec le gestionnaire de persistance (les deux utilisent les getter/setter).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X