J'ai parcouru de nombreuses théories sur ce qu'est l'encapsulation et les trois techniques de sa mise en œuvre, qui sont l'association, l'agrégation et la composition.
L'encapsulation est la technique consistant à rendre les champs d'une classe privés et à fournir l'accès aux champs via des méthodes publiques. Si un champ est déclaré privé, il n'est accessible à personne en dehors de la classe, masquant ainsi les champs de la classe. Pour cette raison, l'encapsulation est également appelée masquage des données.
L'encapsulation peut être décrite comme une barrière de protection qui empêche l'accès aléatoire au code et aux données par un autre code défini en dehors de la classe. L'accès aux données et au code est étroitement contrôlé par une interface.
Le principal avantage de l'encapsulation est la possibilité de modifier notre code implémenté sans casser le code des autres utilisateurs de notre code. Avec cette fonctionnalité, l'encapsulation donne la maintenabilité, la flexibilité et l'extensibilité à notre code.
L'association est une relation où tous les objets ont leur propre cycle de vie et il n'y a pas de propriétaire. Prenons un exemple d'enseignant et d'élève. Plusieurs étudiants peuvent s'associer à un seul enseignant et un seul étudiant peut s'associer à plusieurs enseignants, mais il n'y a pas de propriété entre les objets et les deux ont leur propre cycle de vie. Les deux peuvent créer et supprimer indépendamment.
L'agrégation est une forme d'association spécialisée dans laquelle tous les objets ont leur propre cycle de vie, mais il y a propriété et un objet enfant ne peut pas appartenir à un autre objet parent. Prenons un exemple de département et d’enseignant. Un seul enseignant ne peut pas appartenir à plusieurs départements, mais si nous supprimons le département, l'objet enseignant ne sera pas détruit. Nous pouvons le considérer comme une relation "a-un".
La composition est encore une forme spécialisée d'agrégation et nous pouvons appeler cela une relation de "mort". Il s'agit d'un fort type d'agrégation. L'objet enfant n'a pas de cycle de vie et si l'objet parent est supprimé, tous les objets enfant seront également supprimés. Reprenons un exemple de relation entre la maison et les chambres. La maison peut contenir plusieurs pièces mais il n'y a pas de vie indépendante d'une pièce et aucune pièce ne peut appartenir à deux maisons différentes. Si nous supprimons la maison, la pièce sera automatiquement supprimée.
La question est:
Maintenant, ce sont tous des exemples du monde réel. Je cherche une description sur la façon d'utiliser ces techniques dans le code de classe réel. Je veux dire quel est l'intérêt d'utiliser trois techniques différentes pour l'encapsulation, Comment ces techniques pourraient être mises en œuvre et Comment choisir la technique applicable à la fois.
La distinction entre association, agrégation et composition telle que vous la décrivez est un héritage qui remonte aux temps anciens de la gestion manuelle de la mémoire. Par exemple, en C++, la mémoire utilisée par les objets doit être libérée manuellement et il est donc primordial de concevoir soigneusement le cycle de vie des objets composés. Alors que la distinction entre agrégation et composition est encore enseignée par de nombreux manuels, elle est essentiellement hors de propos lors de la programmation dans des environnements avec gestion automatique de la mémoire. Si vous avez la collecte des ordures, elles ne sont que de la composition, point final.
L'encapsulation, d'autre part, est un principe beaucoup plus général que ce que vous décrivez. C'est avant tout l'idée de regrouper les données et les fonctions qui opèrent sur ces données dans un module. Une façon de l'implémenter consiste à garder l'état du module privé et à exposer les modifications apportées à cet état via les services publics. Le client ne peut donc pas accéder à l'état par lui-même mais doit dire au module son intention en envoyant des messages. L'encapsulation n'est donc pas limitée aux objets mais s'applique également aux services. En fait, une façon de regarder les objets est de les considérer comme des services.
Voici un exemple d'encapsulation
public class Counter {
private int n = 0;
public int inc() { return n++; }
}
ou même en utilisant des fonctions lambda
var counter = (function() {
var n = 0;
var inc = function() { return n++; }
return inc;
})();
Dans les deux cas, les données, c'est-à-dire la variable n
, sont regroupées avec la fonction inc
qui opère dessus. Et il n'y a aucun moyen pour qu'une autre fonction puisse accéder à n
, nous avons donc un module encapsulé qui fournit le comptage en tant que service.
NB: exposer tout l'état intérieur d'un objet via des accesseurs est en fait une violation de l'encapsulation. Hélas, c'est une violation si courante que beaucoup la confondront avec une bonne conception orientée objet.
L'encapsulation est la technique consistant à rendre les champs d'une classe privés et à fournir l'accès aux champs via des méthodes publiques. Si un champ est déclaré privé, il n'est accessible à personne en dehors de la classe, masquant ainsi les champs de la classe. Pour cette raison, l'encapsulation est également appelée masquage des données.
public class Test{
private String name;
private int age;
public int getAge(){
return age;
}
public String getName(){
return name;
}
}
Référez-vous à cette question aussi .
L'association indique la relation entre les objets. Exemple: l'ordinateur utilise le clavier comme périphérique d'entrée.
Une association est utilisée lorsqu'un objet veut qu'un autre objet effectue un service pour lui.
L'agrégation est un cas particulier d'association. Une association directionnelle entre les objets. Quand un objet "a-un" un autre objet, alors vous avez une agrégation entre eux.
ex: La pièce a une table, mais la table peut exister sans la pièce.
class Room {
private Table table;
void setTable(Table table) {
this.table = table;
}
}
La composition est un cas particulier d'agrégation. La composition est plus restrictive. Lorsqu'il y a une composition entre deux objets, l'objet composé ne peut exister sans l'autre objet. Cette restriction n'est pas là dans l'agrégation. ex: pièces dans une maison, qui ne peuvent exister après la durée de vie de la maison.
class House {
private Room room;
House(Room roomSpecs) {
room = new Room(roomSpecs);
}
}
La composition est une technique de conception pour implémenter une relation has-a dans les classes, soit par héritage, soit par composition d'objet pour la réutilisation de code.
L'une des meilleures pratiques dans la programmation Java est d'utiliser la composition sur l'héritage
Je pense franchement que ces notions enseignées à l'université ont leur importance dans les contextes d'orientation d'objet et de conception de classe. Ces concepts nous aident beaucoup lorsqu'il s'agit de modéliser un système à partir de zéro. L'association, l'agrégation et la composition appartiennent exclusivement au diagramme de classes UML et sont complètement indépendantes des contraintes technologiques comme les problèmes de mémoire.
De plus, vous devez également tenir compte du niveau supérieur ou des objectifs commerciaux du système que vous modélisez. Nous avons des objets comme House and Room dans notre système à l'étude, mais ne pouvons pas être fortement liés (via la composition). Par exemple, si je modélise un système immobilier, je devrai peut-être savoir quelle pièce appartient à quelle maison. Mais laisse que je modélise un système d'arpentage ou de recensement où je veux savoir combien de personnes vivent dans chaque pièce de la maison dans une certaine zone, alors je n'ai tout simplement pas besoin de relier une pièce avec une maison via la composition.
Un autre exemple pourrait être un verger et certains types de fruits. Disons que je ne peux considérer un verger que lorsque j'ai Apple arbres plantés à l'intérieur. L'essentiel est que les exigences du système global importent beaucoup.
Encapsulation est l'un des piliers de la conception orientée objet. Vous devez regrouper vos données et les opérations que vous effectuerez sur vos données. vous devez également cacher certains attributs de votre objet du monde extérieur afin de permettre à cet objet de survivre dans un état valide. Lorsque 2 objets interagissent, ils doivent interagir entre eux via une interface. Et c'est ce que l'encapsulation garantit lorsque nous concevons notre système OO.
Voici comment ces concepts sont appliqués au code:
ASSOCIATION: L'association indique la relation entre les objets. Il permet au programmeur de savoir quelles méthodes écrire dans leurs classes pour les faire interagir. Vous pouvez trouver plusieurs exemples de codes et de diagrammes de classes pour comprendre l'association. Dans votre exemple d'enseigner et d'étudiant, il y a une relation de enseignement et enseigné par. Ainsi, vous écrirez simplement un ensemble de méthodes (appelées techniquement interface) grâce auxquelles vous pourrez savoir quel élève a quels enseignants et quel enseignant a quels élèves. L'association permet également au modélisateur de système d'aider le concepteur de base de données sur les attributs et les champs qui doivent être conservés dans la base de données.
COMPOSITION: Si un objet fait partie intégrante d'un autre objet, je devrai peut-être indiquer cette relation dans le constructeur de l'autre objet. Par exemple, dans votre scénario de maisons et de pièces, nous pouvons écrire le code suivant au cas où nous voudrions savoir quelle pièce appartient à quel type de maison.
class House{
string _HouseType;
public:
void setHouseType(string house_type)
{
this. _HouseType = house_type;
}
string getHouseType()
{
return _HouseType;
}
};
House HouseObject = new House();
class Room{
public:
Room(string HouseType) {
this._HouseType = HouseObject.getHouseType(); //as in my system a room cannot exist without a house
}
};
Le programmeur s'assurera également en invoquant destructeurs de l'objet, que le destructeur de l'autre objet sera également invoqué. C'est crucial.
AGGREGATION: Disons que si la relation entre les objets est faible alors nous pour le programmeur, cela signifierait utiliser une variable d'instance à la place pour indiquer la relation. Ensuite, écrivez un functon mutateur (setter) pour donner de la valeur à cet objet à partir d'un autre.
class Department{
string dept_name;
public:
void setDeptName(string name)
{
this.dept_name=name;
}
string getDeptName()
{
return dept_name;
}
};
Department DepartmentObject = new Department();
class Teacher{
string dept_name;
public:
setDeptName(string name)
{
this.dept_name = DepartmentObject.getDeptName(); //You only need to invoje this method when needed (aggregation)
}
}
};
L'utilisation de ces techniques entraîne généralement des pratiques de conception telles que SOLIDE ou divers modèles de conception .
Le but d'utiliser des modèles, des pratiques et autres est de décrire une solution à un problème spécifique qui est également maintenable et extensible. Vous devez simplement acquérir suffisamment d'expérience pour savoir où utiliser quel modèle ou technique.
OK, mappons cela à certaines propriétés de base plutôt qu'à des concepts abstraits qui n'ont de sens qu'une fois que vous comprenez ce qu'ils signifient. Comme certains commentateurs, je ne suis pas d'accord avec la réponse acceptée, je dis que ce sont des concepts indépendants de la gestion de la mémoire.
Encapsulation
Vous voulez cacher la complexité au client, publier uniquement les éléments importants du point de vue du client, ce qui facilite les choses pour le client. En prime, vous avez la certitude que rien ne peut perturber le code encapsulé. Tant que vous respectez l'interface et la fonctionnalité, vous pouvez retravailler des choses et être assuré que vous ne casserez rien. La dépendance concerne uniquement l'interface publiée.
L'encapsulation est l'un des principaux piliers de l'orientation des objets. Ce n'est pas un modèle, c'est un principe et cela peut s'appliquer à la logique et aux données. C'est juste un avantage de base d'utiliser des classes en premier lieu, pas quelque chose que vous verriez explicitement indiqué dans un diagramme ou un document de conception.
Association
Il s'agit d'un concept très vague qui décrit simplement une dépendance entre les objets. Un objet connaît l'existence d'un autre objet et peut utiliser ses fonctionnalités à un moment donné. Dans un diagramme, l'association vous avertirait qu'il existe une dépendance et que le changement d'un objet peut avoir un impact sur l'autre. Ce n'est pas une technique à appliquer lorsque vous avez un problème à résoudre, c'est plutôt une réalité que vous devez savoir quand elle est là. C'est une relation. Comme une facture ayant une propriété Orders. La commande et la facture ont leur propre cycle de vie. L'une concerne les marchandises et l'autre le paiement, ce qui les rend essentiellement indépendantes mais il est important de savoir pour quelles marchandises sont payées.
Confinement
J'ajoute cela car il appartient à la série et rendra l'agrégation plus significative. Je n'entends plus beaucoup le terme utilisé dans un contexte SE, mais je pense qu'il est toujours utile. Le confinement implique l'encapsulation mais concerne strictement les instances d'objet privées de la classe contenante. La fonctionnalité des objets contenus est exposée de manière sélective via des interfaces publiques. La classe conteneur contrôle le cycle de vie des objets contrôlés. Vous l'utilisez lorsque vous avez besoin de certaines fonctionnalités d'une classe existante pour rendre fonctionnelle la classe conteneur. Il peut s'agir d'un analyseur XML et le client de la classe conteneur peut ne jamais voir ou savoir quoi que ce soit lié à XML. En tant que métaphore, considérez l'objet contenu comme un employé de back-office. Les clients ne rencontrent jamais ces personnes, mais ils sont nécessaires pour fournir le service.
agrégation
Cela ressemble beaucoup au confinement, sauf pour le contrôle du cycle de vie et la visibilité des objets agrégés. Les objets agrégés sont déjà disponibles dans un contexte différent et sont gérés par une entité différente. L'agrégateur propose simplement une façade, un portail vers les objets agrégés. Lorsque le client adresse l'agrégat, il obtient l'interface de l'objet agrégat lui-même, pas un wrapper autour de lui. Le point de l'agrégat est d'offrir un regroupement logique des choses. Pensez à un point d'accès aux services ou à un autre objet wrapper.
Composition
Il me semble que c'est le terme le plus contemporain pour le confinement, peut-être parce qu'il a été inventé dans un livre populaire d'origine relativement récente. Lorsque le confinement se concentre sur les aspects techniques des relations d'objet, la composition est généralement utilisée dans le contexte des décisions de conception, plus spécifiquement comme alternative plus flexible à l'héritage.
Il ne dit pas grand-chose sur la nature des relations d'objet ou de la propriété, il indique simplement que la fonctionnalité est implémentée en combinant la fonctionnalité des classes existantes. Par conséquent, je dirais qu'il n'appartient pas à cette série car il ne dit rien sur les aspects techniques d'une mise en œuvre où les autres le font.