MofuMofu2 / typescript-sandbox

MIT License
0 stars 0 forks source link

キャッシュクラス #58

Closed MofuMofu2 closed 1 year ago

MofuMofu2 commented 1 year ago

キーと値のペアを保存するためのジェネリックなキャッシュクラスCacheを作成してください。このクラスは、set(key: K, value: V)とget(key: K): V | undefinedという2つのメソッドを持つべきです。

class Cache<K, V> { // ここに実装 }

MofuMofu2 commented 1 year ago

set(key: K, value: V) というメソッドとget(key: K): V | undefinedというメソッドが必要ということだった。 まずは追加してみる。

MofuMofu2 commented 1 year ago

キャッシュクラスの要件をもう少し整理したいです。setメソッドとコンストラクターはどのように使い分けるといいですか?コードの実装例を出力せずに回答をいただきたいです。

setメソッドとコンストラクタの使い分けについて説明します。

コンストラクタ:

コンストラクタは、クラスのインスタンスが生成されるときに一度だけ実行される特殊なメソッドです。通常、コンストラクタ内で行われる操作は以下の通りです:

  1. メンバ変数の初期化。
  2. インスタンスの生成時に必要な初期設定。

例えば、Cacheクラスでは、内部でキャッシュデータを保持するためのオブジェクトやマップの初期化をコンストラクタ内で行うでしょう。

setメソッド:

setメソッドは、キャッシュに新しいキーと値のペアを追加したり、既存のキーの値を更新したりするためのものです。キャッシュクラスのインスタンスがすでに生成されている状態で、キーと値のペアを追加するためにsetメソッドを使用します。

使い分け:

  1. コンストラクタ: インスタンスの生成と初期設定に使用します。例えば、内部データ構造の初期化や、キャッシュの容量のような、特定の初期パラメータを設定することが考えられます。

  2. setメソッド: すでに生成されているキャッシュのインスタンスに、新しいキーと値のペアを追加したり、既存のペアの値を更新したりするために使用します。

考慮すべき点:

この説明をもとに、キャッシュクラスを設計する際のアプローチを考えることができます。

MofuMofu2 commented 1 year ago

もっと訳がわからなくなってきた。setでk,vを更新するということ?

MofuMofu2 commented 1 year ago

提供されたCacheClassを確認しましたが、実際のキャッシュの動作とは異なります。

以下の問題点があります:

  1. このクラスは1つのキーと値のペアしか保存できません。通常のキャッシュは複数のキーと値のペアを保存することができるべきです。
  2. setメソッドは既存のキーと値を上書きするだけです。これは1つのキーと値のペアしか保存しないためのものですが、これはキャッシュの本来の動作とは異なります。

以下のように修正することで、実際のキャッシュの動作を模倣することができます:

  1. 内部的にはキーと値のペアを保存するためのオブジェクトまたはMapを使用します。
  2. setメソッドを使用して、キーと値のペアをキャッシュに追加または更新します。
  3. getメソッドを使用して、指定されたキーに関連付けられている値を取得します。

以下は修正後のCacheClassのサンプルです:

class CacheClass<K, V> {
  private cache: Map<K, V>;

  constructor() {
    this.cache = new Map<K, V>();
  }

  set(key: K, value: V): void {
    this.cache.set(key, value);
  }

  get(key: K): V | undefined {
    return this.cache.get(key);
  }
}

このクラスでは、Mapを使用して内部的にキーと値のペアを保存します。setメソッドを使用してキャッシュにデータを追加または更新し、getメソッドを使用してデータを取得します。

MofuMofu2 commented 1 year ago

内部的にはキーと値のペアを保存するためのオブジェクトまたはMapを使用します。

MapはArray.prototype.map以外にもあるのを初めて知った。 https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Map

2と3は次のAPIを使って実装している。

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Map/get https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Map/set

MofuMofu2 commented 1 year ago

private cache: Map<K, V>; の部分とコンストラクターについてもう少し詳しく解説いただけますか?

もちろん、詳しく解説します。

1. private cache: Map<K, V>;

この行は、クラスCacheClassの中でcacheという名前のプライベートメンバ変数を宣言しています。この変数は、キーと値のペアを保持するためのMapオブジェクトを表しています。

2. コンストラクタ

constructor() {
    this.cache = new Map<K, V>();
}

この設計により、CacheClassは内部的にMapを使用してキーと値のペアを効率的に管理することができます。外部からは、この内部のMapの詳細を知ることなく、setgetメソッドを通じてキャッシュの操作を行うことができます。

MofuMofu2 commented 1 year ago

うーん、Mapとオブジェクトの違いがよくわからないので質問してみる。

MofuMofu2 commented 1 year ago

MapとObjectの違いがよくわからないので解説いただけますか?keyとvalueが実行時に型が決まるのでジェネリクスを使うのはわかりましたが、オブジェクト型で指定するときと指定しないときがよくわからないです。

了解しました。まずは、MapObjectの違いから説明し、次にTypeScriptでのオブジェクト型の指定に関して説明いたします。

1. MapObjectの違い

Object:

Map:

2. TypeScriptでのオブジェクト型の指定

TypeScriptでは、オブジェクトの型を指定する方法が複数あります。

指定しない場合: TypeScriptは型推論を用いてオブジェクトの型を自動的に推論します。

let obj = { name: "Alice", age: 25 }; 
// objの型は { name: string; age: number; } と推論される

明示的に型を指定する場合: オブジェクトの型を明示的に指定できます。

let obj: { name: string; age: number; } = { name: "Alice", age: 25 };

インターフェースや型エイリアスを使用する場合: より複雑なオブジェクトの型を定義する場合、インターフェースや型エイリアスを利用することが推奨されます。

interface Person {
    name: string;
    age: number;
}

let obj: Person = { name: "Alice", age: 25 };

このように、TypeScriptではオブジェクトの型をどのように指定するか、または推論を利用するかに応じて柔軟に対応できます。どの方法を選ぶかは、ケースやコードの構造、チームのコーディングガイドラインなどに依存します。


JavaScriptだと全てがobjectで、ここから派生している。なので組み込み = プロトタイプがある

https://jsprimer.net/basic/prototype-object/ https://developer.mozilla.org/ja/docs/Learn/JavaScript/Objects/Object_prototypes

シンボルはユニークな識別子(かぶっちゃだめ)のこと。普段は用途が思いつかなさそう。

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Symbol https://ja.javascript.info/symbol


key-valueのペアがくるが、何が出てくるかは実行しないとわからないみたいなときはジェネリクスを使う。 基本はinterfaceを指定することになりそう。