OOP - カプセル化

Patricia Arquette
リリース: 2024-12-14 17:39:11
オリジナル
724 人が閲覧しました

OOP - Encapsulation

何???

カプセル化 は、データと関数を 1 つのユニット (カプセル) にバンドルするプロセスであり、一部のデータ/メソッドへのアクセスを制限することもできます。

これは、継承、ポリモーフィズム、データ抽象化と並ぶ OOP の 4 つの柱の 1 つです。

なぜ?

盲目的な仮定を受け入れ、あらゆる場所でカプセル化を使用して続行する方が簡単ですが、カプセル化を正しい方法で使用できるようにその理由を理解することが重要です。

タスクの例を見て、その理由を理解してみましょう。

タスク:

次のような生徒の成績計算ツールを構築します。

  • 平均点を計算する
  • 生徒が不合格か合格かを判断します
  • 主題マークのいずれかが無効な場合はエラーをスローします (< 0 || > 100)

解決策 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 の問題:

これは間違いなく期待どおりの結果を達成しますが、それに関連する問題がいくつかあります。いくつか例を挙げると、

    ここにあるすべての実装はグローバルにアクセス可能であり、将来の貢献者による使用を制御することはできません。
  1. データと操作は分離されているため、どの関数がデータに影響を与えるかを追跡するのが困難です。何が呼び出されているか、実行の一部であるかを理解するには、すべてのコードを注意深く調べる必要があります。
  2. ロジックが拡大するにつれて、関数の管理が難しくなります。変更を行うと、密結合により無関係なコードが壊れる可能性があります。
問題を解決するにはどうすればよいですか?

カプセル化を組み込むか、以下の 2 つの手順を実行してより明確にします。

    データと機能へのアクセス制御
  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());

ログイン後にコピー
上記の解決策の注意事項、

    メソッド totalMarks、subjectCount、validateMarks、およびメンバー変数 Student は公開されず、クラス オブジェクトによってのみ使用できます。
2.データ生徒は、そのあらゆる動作にバンドルされています。

以上がOOP - カプセル化の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:dev.to
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート