dart-api-design について
Dart 開発者向けの API 設計ガイドです。命名、型シグネチャ、クラス修飾子、カプセル化、引数の選び方を扱い、設計チェックリストと `dart analyze` による検証手順も含みます。
主な機能
- 01命名と API の規約
- 02Dart 3 クラス修飾子の指針
- 03カプセル化と等価性の規則
- 04型と引数の設計
- 05API チェックリストと解析手順
活用シーン
- 01新しい Dart ライブラリ API の設計
- 02クラス階層と公開メンバーのレビュー
- 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 を確定する前に、すべての警告を修正してください。
- 注釈の不足、未処理の sealed class switch ケース、リンター違反を検出するため、
コメント
Markdown 対応