L'encapsulation est le processus de regroupement de données et de fonctions dans une seule unité (c'est-à-dire une capsule), elle peut également limiter l'accès à certaines données/méthodes.
C'est l'un des quatre piliers de la POO, avec l'héritage, le polymorphisme et l'abstraction des données.
Il est plus facile de partir d'une hypothèse aveugle et de procéder à l'encapsulation à tous les endroits, mais il est important de comprendre le pourquoi afin de pouvoir l'utiliser de la bonne manière.
Essayons de comprendre le(s) pourquoi en regardant un exemple de tâche.
Créez un calculateur de résultats d'élèves qui devrait,
Solution 1 : la voie non encapsulée
L'idée est simplement de résoudre le problème, j'ai donc choisi la manière de Programmation procédurale d'y parvenir qui, je pense, pourrait montrer un bon contraste et rendre le problème plus évident.
type Subject = "english" | "maths"; interface IStudent { name: string; marks: Record<Subject, number>; } // Receive Input const studentInput: IStudent = { name: "John", marks: { english: 100, maths: 100, }, }; // Step1: Validate the provided marks Object.keys(studentInput.marks).forEach((subjectName) => { const mark = studentInput.marks[subjectName as Subject]; if (mark > 100 || mark < 0) { throw new Error(`invlid mark found`); } }); // Step2: find the total marks const totalMarks = Object.keys(studentInput.marks).reduce( (accumulator: number, current: string) => studentInput.marks[current as Subject] + accumulator, 0 ); // Step3: find the average const average = totalMarks / Object.keys(studentInput.marks).length; // Step4: find the result const boolResult = average > 40; // Step 5: print result console.log(boolResult); console.log(average);
Problèmes avec la solution 1 :
Cela permet certainement d'obtenir le résultat attendu, mais plusieurs problèmes y sont associés. Pour n'en nommer que quelques-uns,
- Chaque implémentation ici est accessible globalement et il n'y a aucun contrôle sur son utilisation par les futurs contributeurs.
- Les données et les opérations sont séparées, ce qui rend difficile le traçage des fonctions qui affectent les données. Vous devrez parcourir attentivement chaque morceau de code pour comprendre ce qui est appelé et ce qui fait partie d'une exécution.
- Les fonctions deviennent plus difficiles à gérer à mesure que la logique évolue. Les modifications peuvent casser du code sans rapport en raison d'un couplage étroit.
En incorporant l'encapsulation ou en la rendant plus évidente en suivant les deux étapes ci-dessous,
Solution 2 : La voie encapsulée
type SubjectNames = "english" | "maths"; interface IStudent { name: string; marks: Record<SubjectNames, number>; } class ResultCalculator { protected student: IStudent; constructor(student: IStudent) { this.student = student; } isPassed(): boolean { let resultStatus = true; Object.keys(this.student.marks).forEach((subject: string) => { if (this.student.marks[subject as SubjectNames] < 40) { resultStatus = false; } }); return resultStatus; } getAverage(): number { this.validateMarks(); return this.totalMarks() / this.subjectCount(); } private validateMarks() { Object.keys(this.student.marks).forEach((subject: string) => { if ( this.student.marks[subject as SubjectNames] < 0 || this.student.marks[subject as SubjectNames] > 100 ) { throw new Error(`invalid mark`); } }); } private totalMarks() { return Object.keys(this.student.marks).reduce( (acc, curr) => this.student.marks[curr as SubjectNames] + acc, 0 ); } private subjectCount() { return Object.keys(this.student.marks).length; } } // Receive Input const a: IStudent = { name: "jingleheimer schmidt", marks: { english: 100, maths: 100, }, }; // Create an encapsulated object const result = new ResultCalculator(a); // Perform operations & print results console.log(result.isPassed()); console.log(result.getAverage());
avis dans la solution ci-dessus,
2.l'étudiant en données est associé à chacun de ses comportements.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!