9️⃣

[読書メモ]オブジェクト設計スタイルガイド 4章9節 with TypeScript

2024/02/19に公開

オブジェクト設計スタイルガイドを読みながら、TypeScriptでやるならどうやるかを考えながら書きました。
要約的に読める内容になっていると思うので、サクッと3分ぐらいで読める記事となっています。
https://www.oreilly.co.jp/books/9784814400331/

4.9 イミュータブルオブジェクトを比較するときは、同一性ではなく同等性を比較する

同一性(Identity)

  • 同一性は、2つのオブジェクトが厳密に同じオブジェクトであるかどうかを示します。つまり、メモリ上の同じ場所を指しているかどうかです。
  • 同一性の比較は、2つの参照が同じオブジェクトを指している場合にのみtrueになります。
  • 多くのプログラミング言語では、===(JavaScriptやTypeScriptなど)やis(Pythonなど)を使用して同一性をチェックします。

同等性(Equality)

  • 同等性は、2つのオブジェクトの内容や値が等しいかどうかを示します。オブジェクトが異なるメモリ領域に存在していても、その内容が等しい場合、これらのオブジェクトは同等とみなされます。
  • 同等性の比較は、オブジェクトの状態や値を基にして行われます。例えば、2つの文字列オブジェクトが異なる場所にあっても、その文字列の内容が同じであれば、これらは等しいとみなされます。
  • 多くのプログラミング言語では、==(JavaScriptなど)、equals()メソッド(Javaなど)、==演算子(Pythonなど、ただしPythonの場合は==は同等性のチェックに使われ、同一性のチェックにはisを使用)を使用して同等性をチェックします。

イミュータブルオブジェクトの場合は、同等性(Equality)をテストすること。
かといってむやみに、equalsメソッドを用意するのも無駄ではある。
親クラスに実装しておいて、継承するのが楽そうではある。

class Player {
  constructor(private position: Position) {}

  current() {
    return this.position;
  }

  moveLeft(step: number): void {
    this.position = this.position.toTheLeft(step);
  }
}

class Position {
  constructor(private _x: number, private _y: number) {}

  private clone() {
    return new Position(this._x, this._y);
  }

  toTheLeft(steps: number) {
    let copy = this.clone();
    copy._x = copy._x - steps;
    return copy;
  }
}

// イミュータブルなメソッドの場合
test("it_can_move_to_the_left", () => {
  const init_position = new Position(10, 20);
  const player = new Player(init_position);

  expect(init_position).toBe(player.current()); // ①

  player.moveLeft(4);

  expect(player.current()).toMatchObject(new Position(6, 20)); // ②
});

①は、同一性のチェックでok
②は、同等性のチェックをする

Discussion