カプセル化 は、データと関数を 1 つのユニット (カプセル) にバンドルするプロセスであり、一部のデータ/メソッドへのアクセスを制限することもできます。
これは、継承、ポリモーフィズム、データ抽象化と並ぶ OOP の 4 つの柱の 1 つです。
盲目的な仮定を受け入れ、あらゆる場所でカプセル化を使用して続行する方が簡単ですが、カプセル化を正しい方法で使用できるようにその理由を理解することが重要です。
タスクの例を見て、その理由を理解してみましょう。
次のような生徒の成績計算ツールを構築します。
解決策 1: カプセル化されていない方法
目的は単に問題を解決することなので、それを達成するために手続き型プログラミング という方法を選択しました。これは、良いコントラストを示し、問題をより明白に見せることができると信じています。
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);
解決策 1 の問題:
これは間違いなく期待どおりの結果を達成しますが、それに関連する問題がいくつかあります。いくつか例を挙げると、
問題を解決するにはどうすればよいですか?ここにあるすべての実装はグローバルにアクセス可能であり、将来の貢献者による使用を制御することはできません。
- データと操作は分離されているため、どの関数がデータに影響を与えるかを追跡するのが困難です。何が呼び出されているか、実行の一部であるかを理解するには、すべてのコードを注意深く調べる必要があります。
- ロジックが拡大するにつれて、関数の管理が難しくなります。変更を行うと、密結合により無関係なコードが壊れる可能性があります。
解決策 2: カプセル化された方法
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());
以上がOOP - カプセル化の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。