web-dev-qa-db-fra.com

Avez-vous besoin de penser à l'encapsulation si vous pouvez assurer une immuabilité?

encapsulation

Dans la programmation orientée objet (OOP), l'encapsulation fait référence au regroupement de données avec les méthodes qui fonctionnent sur ces données ou la limitation de l'accès direct à certains des composants d'un objet . 1 encapsulation est utilisé pour Cachez les valeurs ou l'état d'un objet de données structuré à l'intérieur d'une classe, empêchant ainsi l'accès direct des parties non autorisées. Wikipedia - encapsulation (programmation informatique

Immutabilité

Dans la programmation orientée objet et fonctionnelle, un objet immuable (objet inchangé) est un objet dont l'état ne peut pas être modifié après sa création . Wikipedia - objet immuable

Si vous pouvez vous garantir une immuabilité, avez-vous besoin de penser à l'encapsulation?

J'ai vu ces concepts utilisés pour expliquer des idées dans la programmation orientée objet (OOP) et la programmation fonctionnelle (FP).

J'ai essayé d'enquêter sur les sujets de l'encapsulation, de l'immuabilité et de leur relation les uns avec les autres. Je n'ai pas trouvé de poste qui a explicitement demandé si l'encapsulation est garantie si vous avez une immuabilité.

Merci de me corriger si j'ai mal compris quelque chose sur le sujet de l'encapsulation ou de l'immutabilité. Je souhaite mieux comprendre ces concepts. En outre, dirigez-moi à tout autre article qui a été fait sur le sujet qui répond à la question ci-dessus.

36
Christopher Trotter

Je déteste comment l'encapsulation est toujours encadrée comme empêchant l'accès non autorisé. Si tel était le meilleur moyen d'y penser, l'immuabilité éliminerait effectivement la majeure partie de la nécessité d'encapsulation. En fait, l'immuabilité fait élimine de nombreux cas d'encapsulation overzeale, où le seul but de l'encapsulation était de maintenir les appelants de bouturures.

L'encapsulation est mieux considérée comme fournissant un bon service client. Vous ajoutez une interface plus facile à utiliser et à un niveau d'abstraction plus approprié. C'est comme les TILIDS , un système de tunnels sous Disney Parks. Leur but n'est pas de fournir un espace privilégié où les invités ne sont pas autorisés. Il est d'éviter de gâcher l'expérience et l'immersion des invités. L'immuabilité ne fait aucune différence de la voie à l'encapsulation "Expérience du visiteur".

56
Karl Bielefeldt

L'encapsulation peut signifier que vous masquez le stockage réel des données immuables.

Par exemple.:

class Color
{
  private readonly uint argb;
  public byte Blue => (byte)(argb & 0xFF);

  public Color(byte red, byte green, byte blue, byte alpha)
  {
    argb = alpha << 24 | red << 16 | green << 8 | blue;
  }
}

L'interface (le constructeur et l'octet bleu) cache le fait que les données bleues réelles sont stockées dans le dernier octet d'un UINT. Cet uint pourrait être changé plus tard sur RGBA ou une gamme d'octets sans casser l'interface:

class Color
{
  private readonly byte[] argb;
  public byte Blue => (byte)argb[3];

  public Color(byte red, byte green, byte blue, byte alpha)
  {
    argb = new []{alpha, red, green, blue};
  }
}

Dans ce cas, encapsuler correctement les données (immuables) permettent de modifier la mise en œuvre sans casser l'interface publique.

Donc, oui, cela vaut peut-être la peine de penser à l'encapsulation, même lorsque les données sont immuables.

32
Erno

Si vous pouvez vous garantir une immuabilité, avez-vous besoin de penser à l'encapsulation?

Peut-être, mais probablement pas d'une manière la plupart des gens pensent.


Tout d'abord, réalisez que l'encapsulation (la pratique consistant à cacher la structure interne des données) n'est pas un objectif. C'est un moyen de découplage (qui est à son tour un moyen de abstraction).

Ensuite, vous pouvez obtenir un découplage de manière à ne pas impliquer de déclarer des membres privés sur vos types. L'exemple le plus courant de cela dans la programmation fonctionnelle est la fermeture. Considérez le code suivant en C #:

var lowest = int.Parse(someString);
var filtered = collection.Where<Elem>(x => x >= lowest);

La fonction Where filtres Les résultats basés sur un prédicat qui dépend à son tour d'une valeur que Where ne connaît rien. Tant que la fermeture expose l'interface d'accepter un objet de type Elem et renvoyer un bool, tout fonctionne.

Il pourrait être le cas que le type Elem a tous ses membres entièrement exposés publiquement, Where est entièrement capable d'utiliser ce type dans le cadre d'un filtre et encore complètement découplé de celui-ci. taper. Le découplage est tellement complet que Where et Elem pourrait être défini dans des assemblages entièrement distincts qui ne savent rien les uns des autres, et l'extrait ci-dessus pourrait être dans un troisième assemblage faisant référence à la fois et rien ne change. de savoir si ou comment ça fonctionne.

Ainsi, cacher la structure de vos données est non une condition préalable nécessaire pour obtenir un découplage.

Je suis principalement d'accord avec la réponse de Karl Bielefeldt, mais croyez que l'analogie est un peu désactivée.

L'encapsulation n'est pas une sécurité, son objectif est d'éviter une surcharge d'informations. Considérez les différentes saveurs d'autocompletion/Auto Suggérer/IntelliSense, sur les systèmes à réflexion, suggérant des méthodes privées faciliterait la réflexion et moins d'erreurs. Voulez-vous que votre IDE vous suggère-t-il à ceux de la classe elle-même?

Il y a une limite à ce que vous pouvez garder à l'esprit à la fois. Dans la vieille journée, nous avions l'habitude de faire des variables mondiales, des centaines d'entre elles, éventuellement des milliers et la plupart d'entre elles ont été utilisées dans relativement peu d'endroits. Lorsque vous les avez utilisés, vous avez dû déterminer lequel à utiliser, qu'il soit déjà existé ou non, où il a été changé et où il était lu, et où dans le flux de l'application, la lecture/écriture se produisait. C'était difficile, en travaillant avec ce code, il n'était pas rare d'utiliser la mauvaise variable ou de déclarer un duplicata utilisé à différents endroits, pas plus rare de changer la valeur de manière inappropriée entre les usages. Il est impossible de penser à des centaines de variables à la fois.

L'encapsulation signifie que l'état est exposé là où il devrait être changé, que des actions sont exposées où elles peuvent être utilisées. Si vous avez une classe FOO qui a une méthode privée CalcarxSety qui calcule une valeur intermédiaire utilisée dans la méthode privée Barx, utilisée dans la barre de méthode, en tant qu'utilisateur de la classe FOO, je ne devrais pas être chargé de la connaissance que CalcarxSsty existe , parce que je n'ai aucune idée de ce qu'il fait et que je ne peux pas l'utiliser de manière fiable. Sachant que FOO a une méthode nommée CalcarsetX, est approximativement utile pour moi qu'un utilisateur de la classe comme numéro de ligne utilisé pour créer la classe ou si la barre utilise une variable nommée I ou X.

2
jmoreno