mcpField
D
dart-api-design

dart-api-design

github.com/dart-lang開発53266 回インストール2 週間前に更新
リポジトリ

dart-api-design について

Dart 開発者向けの API 設計ガイドです。命名、型シグネチャ、クラス修飾子、カプセル化、引数の選び方を扱い、設計チェックリストと `dart analyze` による検証手順も含みます。

主な機能

  1. 01命名と API の規約
  2. 02Dart 3 クラス修飾子の指針
  3. 03カプセル化と等価性の規則
  4. 04型と引数の設計
  5. 05API チェックリストと解析手順

活用シーン

  1. 01新しい Dart ライブラリ API の設計
  2. 02クラス階層と公開メンバーのレビュー
  3. 03`dart analyze` 実行前のシグネチャ確認

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/dart-lang/skills --skill dart-api-design

インストール後、Claude Code で/dart-api-designを入力して読み込まれたか確認します。

詳細

効果的な Dart API の設計

目次

命名規則

既存のドメイン知識やコアライブラリの知識を活用できるよう、一貫性があり、内容を適切に表す名前を徹底してください。

  • プロパティと変数:
    • ブール値以外のプロパティには名詞句を使用してください(例:pageCount、context.lineWidth)。
    • ブール値のプロパティには、命令形ではない動詞句を使用してください(例:isEmpty、canClose)。「肯定形」の名前(例:isNotDisconnectedではなくisConnected)を優先してください。
  • メソッドと関数:
    • 副作用の大きい操作には命令形の動詞句を使用してください(例:list.add()、window.refresh())。
    • 値を返すことが主な目的の場合は、名詞句または命令形ではない動詞句を使用してください(例:list.elementAt(3))。
    • メソッド名をgetで始めるのは避けてください。ゲッターまたは内容を表す動詞を使用してください(例:downloadData())。
    • 状態を新しいオブジェクトにコピーするメソッドには、to___()という名前を付けてください(例:list.toSet())。
    • 元のオブジェクトに裏付けられた別の表現を返すメソッドには、as___()という名前を付けてください(例:table.asMap())。
  • 型パラメーター:標準的な略記に従ってください:要素にはE、キー/値にはK/V、戻り値の型にはR、単一の型にはT/S/Uを使用します。

クラス修飾子とアーキテクチャ

Dart 3のクラス修飾子を使って、拡張を想定した設計と実装のカプセル化を行ってください。修飾子を適用して、外部ライブラリからのアクセスを制御します。

  • abstract:インターフェースの具象実装が必要なクラスを定義する場合に使用します。インスタンス化できません。
  • base:クラスの実装を継承するよう強制する場合に使用します。同じライブラリの外部でのimplementsを禁止します。基底クラスのコンストラクターが呼び出されることを保証します。
  • interface:純粋なインターフェースを定義する場合に使用します。implementsは許可しますが、同じライブラリの外部でのextendsは禁止します。壊れやすい基底クラスの問題を軽減します。
  • final:型階層を閉じる場合に使用します。ライブラリの外部でのextendsとimplementsの両方を禁止します。安全で段階的なAPI変更を保証します。
  • sealed:既知の列挙可能なサブタイプの集合を作成する場合に使用します。サブタイプに対する網羅的なswitch文が可能になります。暗黙的に抽象クラスになります。

注:適切な場合は修飾子を組み合わせてください(例:純粋なインターフェースにはabstract interface class)。

メンバーとカプセル化

  • カプセル化:パブリックフィールドは避けてください。状態へのアクセスと変更を制御するため、カプセル化にはゲッターとセッターを使用してください。
  • ゲッター:概念上、プロパティにアクセスする操作にはゲッターを使用してください。引数を取らず、結果を返し、ユーザーから見える副作用がなく、冪等である必要があります。
  • セッター:概念上、プロパティを変更する操作にはセッターを使用してください。引数を1つだけ取り、状態を変更し、冪等である必要があります。
    • 対応するゲッターのないセッターを定義しないでください。
    • セッターに戻り値の型を指定しないでください(セッターの戻り値は常にvoidです)。
  • メソッドのカスケード:流れるようなインターフェースを可能にするためだけに、メソッドからthisを返すことは避けてください。代わりにDartのカスケード演算子(..)を使用してください。
  • 等価性:
    • ==をオーバーライドする場合は、hashCodeもオーバーライドしてください。
    • 可変クラスにカスタムの等価性を定義することは避けてください。
    • ==のパラメーターをnullableにしないでください(nullチェックは言語が自動的に処理します)。

型とシグネチャ

  • 型エイリアス:複雑な関数シグネチャを簡潔にするには、型エイリアス(typedef)を使用してください。最新の構文を使用します:typedef Comparison<T> = int Function(T a, T b);。
  • インライン関数:単純で一度限りのコールバックには、typedef よりもインライン関数型を優先してください(例:void Function(Event) callback)。
  • 型注釈:
    • 初期化式のない変数には型注釈を付けてください。
    • ローカル関数以外の宣言では、戻り値の型とパラメーターの型に注釈を付けてください。
    • 初期化済みのローカル変数や、型推論されるクロージャーパラメーターに重複して型注釈を付けないでください。
  • ジェネリクス:完全なジェネリック型を記述してください。不完全なジェネリック型は避けてください(例:Completer<Map>() ではなく Completer<Map<String, int>>() を使用します)。
  • Dynamic と Object:静的チェックを明示的に無効にしたい場合を除き、dynamic の使用は避けてください。あらゆる値を安全に受け入れるには Object? を使用します。
  • 非同期の戻り値:値を生成しない非同期メンバーの戻り値の型には、Future<void> を使用してください。戻り値の型に FutureOr<T> を使用するのは避けてください(呼び出し側で型の確認が必要になります)。

パラメーター

  • 名前付きパラメーター:呼び出し箇所の可読性を高めるため、引数が 2 個を超える関数では名前付きパラメーターを優先してください。
  • ブール値パラメーター:位置指定のブール値パラメーターは避けてください。代わりに名前付きパラメーターを使用します。
    • 名前付きブール値パラメーターでは、is/can/has の接頭辞を省略することを検討してください(例:isPaused: true ではなく Isolate.spawn(..., paused: true) を使用します)。
  • 省略可能な位置指定パラメーター:先行するパラメーターを省略したい場合があるなら、省略可能な位置指定パラメーターは避けてください。代わりに名前付きパラメーターを使用します。
  • 範囲:範囲を受け取るには、start を含み end を含まないパラメーターを使用してください(例:substring(1, 3))。

ワークフロー

タスクの進捗:API の設計と実装

新しい Dart クラスまたはライブラリ API を設計する際に、進捗を追跡するため、このチェックリストをコピーしてください。

  • クラス修飾子を定義する:
    • 実装を持たないコントラクトを定義する場合 -> abstract interface class。
    • 継承が必須の実装を提供する場合 -> base class。
    • 外部からの拡張や実装を許可せず、階層を閉じる場合 -> final class。
    • 網羅的な switch を行うための列挙可能な状態セットを定義する場合 -> sealed class。
  • 状態をカプセル化する:
    • 内部フィールドを非公開にします(_fieldName)。
    • ゲッターを使って状態を公開します。
    • セッターを使って変更を公開します(対応するゲッターがあることを確認してください)。
  • シグネチャを見直す:
    • 引数が 2 個を超える場合、位置指定パラメーターを名前付きパラメーターに変換します。
    • 位置指定のブール値を名前付きブール値に変換します(is/can/has の接頭辞を削除します)。
    • 複雑な関数パラメーターを typedef エイリアスとして抽出します。
  • 型を検証する:
    • 公開シグネチャに暗黙の dynamic 型がないことを確認します。
    • 戻り値の型 FutureOr<T> を Future<T> に置き換えます。
    • 非同期の void メソッドの戻り値の型が Future<void> であることを確認します。
  • バリデーターを実行 -> エラーを確認 -> 修正する:
    • 注釈の不足、未処理の sealed class switch ケース、リンター違反を検出するため、dart analyze を実行します。API を確定する前に、すべての警告を修正してください。

コメント