1. ホーム
  2. coding-style

[解決済み] TypeScriptのInterfaceとClassのコーディングガイドラインに迷う

2022-09-20 18:32:26

質問

私は TypeScriptコーディングガイドライン

そして、私はこの文がかなり不可解だと思いました。

インターフェース名の接頭辞として "I" を使用しないでください。

つまり、このようなものは "I" という接頭辞がなければあまり意味をなさないということです。

class Engine implements IEngine

私は何か明らかなことを見逃していませんか?

もうひとつ、よくわからなかったのが、これです。

クラス

一貫性を保つために、コアコンパイラパイプラインではクラスを使用しないでください。代わりに 関数のクロージャを使用します。

クラスを一切使うなということでしょうか?

誰かが私のためにそれをクリアすることができます願っています:)

どのように解決するのですか?

チームや会社がフレームワーク/コンパイラ/ツールセットを出荷するとき、彼らはすでにいくつかの経験、ベストプラクティスのセットを持っています。彼らはそれをガイドラインとして共有します。ガイドラインは 推奨事項 . もし気に入らなければ無視してもかまいません。 コンパイラはまだ をコンパイルします。 のコードをコンパイルします。 しかし ローマで...

これは、なぜTypeScriptチームが I -を頭につけないことを推奨しています。

理由その1 時代は ハンガリー語表記 の時代は過ぎ去りました。

からの主引数 I -prefix-for-interface 支持者の主な主張は、接頭辞は型がインタフェースであるかどうかを即座に把握する(peeking)のに役立つというものです。接頭辞はすぐに理解するのに役立つという発言は、以下のようなアピールです。 ハンガリー語表記 . I インターフェース名のプレフィックス。 C はクラスに対して A は抽象クラス用です。 s は文字列変数に対応します。 c は const 変数です。 i といった具合です。このような名前の装飾は、識別子の上にマウスを置いたり、ホットキーで型定義に移動したりしなくても、型情報を提供することができることに同意します。この小さな利点は ハンガリー語表記 の欠点と以下に述べるその他の理由によって相殺されています。ハンガリー語表記は最近のフレームワークでは使われていない。C#では I という接頭辞がある(C#ではこれが唯一の接頭辞である)のは、歴史的な理由(COM)がある。振り返ってみると、.NETアーキテクトの一人(Brad Abrams)は、この方がよかったと思う。 を使わないで I プレフィックス . TypeScript は COM-legacy フリーであり、そのため I -というルールはありません。

理由その2 I -プレフィックスがカプセル化の原則に反している。

あなたがあるブラックボックスを手に入れたとしましょう。そのボックスと対話することができる何らかの型参照を取得します。それがインターフェイスであろうとクラスであろうと気にする必要はありません。ただ、そのインターフェースの部分を使えばいいのです。それが何であるか(インターフェイス、特定の実装、抽象クラス)を知ることを要求するのはカプセル化に違反します。

例: 例として、あなたが API設計の神話: 契約としてのインターフェイス を修正する必要があるとします。 ICar インターフェースを削除して Car をベースクラスとします。そして、すべてのコンシューマでそのような置き換えを行う必要があります。 I -というプレフィックスは、ブラックボックス的な実装の詳細に対するコンシューマの暗黙の依存を引き起こします。

理由3 不正な命名からの保護

開発者は、名前についてきちんと考えることを怠っています。ネーミングは コンピュータサイエンスにおける2つの難題 . 開発者がインターフェイスを抽出する必要がある場合、単に文字 I をクラス名に追加するだけで、 インターフェース名が得られます。禁止されるのは I の接頭辞を許さないことで、開発者はインターフェースの適切な名前を選ぶために頭を使わなければならなくなります。選ばれた名前は、接頭辞だけでなく、意図の違いを強調する必要があります。

抽象化の場合 ではない を定義しない ICar インターフェースと、関連する Car クラスがあります。 Car は抽象化されたもので、コントラクトに使用されるものであるべきです。実装は説明的で特徴的な名前であるべきです。 SportsCar, SuvCar, HollowCar .

良い例です。 WpfeServerAutosuggestManager implements AutosuggestManager , FileBasedAutosuggestManager implements AutosuggestManager .

悪い例です。 AutosuggestManager implements IAutosuggestManager .

理由4 適切に選ばれた名前が、あなたを予防接種の対象にする API設計の神話: 契約としてのインターフェイス .

私は実務の中で、クラスのインターフェイス部分を軽率にも別のインターフェイスに重複させてしまう人にたくさん会いました。 Car implements ICar という命名規則があります。クラスのインターフェイス部分を別のインターフェイス型に複製しても、魔法のように抽象化されるわけではありません。インターフェイスが重複していても、具体的な実装を得ることができます。抽象化がうまくいっていない場合、インターフェース部分を複製しても改善されることはないでしょう。抽象化するのは大変な作業なのです。

注:TSでは、モッキングクラスやオーバーロード機能のために別のインターフェースは必要ありません。 クラスのパブリックメンバを記述する個別のインターフェースを作成する代わりに、以下のように使用できます。 TypeScriptユーティリティタイプ . 例えば Required<T> の全てのパブリックメンバで構成される型を構築します。 T .

export class SecurityPrincipalStub implements Required<SecurityPrincipal> {
  public isFeatureEnabled(entitlement: Entitlement): boolean {
      return true;
  }
  public isWidgetEnabled(kind: string): boolean {
      return true;
  }

  public areAdminToolsEnabled(): boolean {
      return true;
  }
}

パブリックメンバを除いた型を構築したい場合は、以下のようにします。 を使うことができます。 .