Encapsulation dans les définitions de classe
-
19-08-2019 - |
Question
Par exemple, utilisez-vous des accesseurs et des mutateurs dans vos définitions de méthodes ou accédez-vous directement aux données? Parfois, tout le temps ou quand à Rome?
La solution
Essayez toujours d'utiliser des accesseurs, même à l'intérieur de la classe. Le seul moment où vous voudriez accéder à l'état directement et non via l'interface publique est si, pour une raison quelconque, vous deviez contourner la validation ou une autre logique contenue dans la méthode d'accès.
Maintenant, si vous vous trouvez dans la situation où vous devez contourner cette logique, vous devez prendre du recul et vous demander si ce besoin trahit ou non une faille dans votre conception.
Modifier: lire Propriétés automatiques vs propriétés explicites d'Eric Lippert dans lesquelles il aborde cette question et explique les choses très clairement. Il s’agit précisément de C #, mais la théorie de la programmation orientée objet est universelle et solide.
Voici un extrait:
Si la raison qui a motivé le changer de mise en œuvre automatiquement propriété à implémenter explicitement la propriété était de changer la sémantique de la propriété alors vous devriez évaluer si la sémantique souhaitée lors de l'accès à la propriété de dans la classe sont identiques à ou différent de la sémantique souhaitée lors de l'accès à la propriété de en dehors de la classe.
Si le résultat de cette enquête est & # 8220; de la classe, le nombre souhaité sémantique d'accès à cette propriété sont différents de ceux souhaités sémantique d'accès à la propriété depuis l'extérieur, votre édition a introduit un bug. Vous devriez réparer le punaise. S'ils sont identiques, alors votre edit n'a pas introduit de bogue; garder la mise en œuvre de la même manière.
Autres conseils
En général, je préfère les accesseurs / mutateurs. De cette façon, je peux modifier l’implémentation interne d’une classe alors que celle-ci fonctionne de la même manière pour un utilisateur externe (ou un code préexistant que je ne souhaite pas interrompre).
Les accesseurs sont conçus pour que vous puissiez ajouter une logique spécifique à la propriété. Tels que
int Degrees
{
set
{
_degrees = value % 360;
}
}
Ainsi, vous voudrez toujours accéder à ce champ par le biais du getter et du setter, et ainsi vous pourrez toujours être sûr que la valeur ne dépassera jamais 360.
Si, comme Andrew l'a mentionné, vous devez ignorer la validation, il est tout à fait possible que la conception de la fonction ou de la validation présente un défaut.
Les accesseurs et les mutateurs sont conçus pour assurer la cohérence de vos données. Par conséquent, même au sein de votre classe, vous devez toujours vous assurer qu'il est impossible d'injecter des données non validées dans ces champs.
MODIFIER
Voir aussi cette question: OO Design: utilisez-vous des propriétés publiques ou privées champs en interne?
Je n'ai pas tendance à partager avec le monde extérieur les "entrailles" de mes cours. Par conséquent, mes besoins internes en données (méthode privée) ont tendance à ne pas être identiques à ceux de mon interface publique, généralement .
Il est assez rare que j'écrive un accesseur / mutateur qu'une méthode privée appellera, mais je suspecte que je sois dans la minorité ici. Peut-être que je devrais en faire plus, mais je n’ai pas tendance à le faire.
Quoi qu’il en soit, c’est ma [patine couverte] deux cents.
Je vais souvent commencer par les propriétés auto privées, puis refactoriser si nécessaire. Je vais refactoriser une propriété avec un champ de base, puis remplacer le champ de base par le champ "réel". magasin, par exemple Session ou ViewState pour une application ASP.NET.
De:
private int[] Property { get; set; }
à
private int[] _property;
private int[] Property
{
get { return _property; }
set { _property = value; }
}
à
private int[] _property;
private int[] Property
{
get
{
if (_property == null)
{
_property = new int[8];
}
return _property;
}
set { _property = value; }
}
à
private int[] Property
{
get
{
if (ViewState["PropertyKey"] == null)
{
ViewState["PropertyKey"] = new int[8];
}
return (int[]) ViewState["PropertyKey"];
}
set { ViewState["PropertyKey"] = value; }
}
Bien sûr, j'utilise ReSharper, cela prend donc moins de temps que de poster.