LoginSignup
17
5

More than 3 years have passed since last update.

Flutter 自体の Style Guide から学ぶ

Last updated at Posted at 2019-04-24

Style-guide-for-Flutter-repo の話。

ふと CONTRIBUTING.md を読んでたら見つけたのでメモ。
全部書くと長いので、個人的に厳選したものだけ簡潔に意訳してます。1

Flutter リポジトリの Style Guide

Getters feel faster than methods

プロパティのゲッターは効率的であるべき という話。
例えば、キャッシュしたり、オーダーに気を遣ったりしよう。

単純な処理じゃない場合はメソッドにしよう。
Web の話で言えば、document.forms より document.getForms() と書かれていてほしい。

Avoid complecting (braiding multiple concepts together)

各 API はそれぞれで完結しているべき という話。

だから、例えば Widget の child の型を見てどうこうするのは良くないよね。

Avoid APIs that encourage bad practices

良くない習慣を助長する API はやめよう という話。

コストの高い処理をするのであれば、それが API で表されているのがあるべき姿。
例えば Future や Stream を返そう。

Avoid exposing API oceans

大雑把に API を公開しちゃダメだよ という話。

例えば、 dart:uiPath.fromSVG() を公開しないのは、Dart で直接実行するのと速度的には差がほぼないから。
そういうのを不用意に公開しないことで、保守,ドキュメント,テストなどの負担を減らせる。

Writing prompts for good documentation

良いドキュメントを残す時の観点はこういうのがあるよね という話。

[例1]
プロパティや引数の型について、議論すべき正常範囲外のケースがないかを検討しよう。 ex) null, 無限, NaN, 空

[例2]
クラスのメンバーについて、相互の影響について考えよう。例えば、他のある値が null の時だけ〇〇になる みたいなことはないか。

[例3]
ライフサイクルに気をつけよう。例えば、誰かが所有しているオブジェクトがあったとして、その dispose() は誰が責任を持って呼ぶのか。

Provide sample code

サンプルコードあると嬉しいよね という話。

適切なフォーマットでサンプルを書く。

/// {@tool sample}
/// An infinite list of children:
///
/// ```dart
/// ListView.builder(
///   padding: EdgeInsets.all(8.0),
///   itemExtent: 20.0,
///   itemBuilder: (BuildContext context, int index) {
///     return Text('entry $index');
///   },
/// )
/// ```
/// {@end-tool}
class ListView { // ...

Use /// for public-quality private documentation

public な API のコメントは必ず /// だよね という話。
品質が十分でない private な API にだけ // を使おう。

Dartdoc-specific requirements

Dartdoc に従ってドキュメント書こう という話。

/// Creates a foobar, which allows a baz to quux the bar.
///
/// The [bar] argument must not be null.
///
/// The `baz` argument must be greater than zero.
Foo({ this.bar, int baz }) : assert(bar != null), assert(baz > 0);

Use asserts liberally to enforce contracts and invariants

assert() はデバッグモードでだけ有効なんだから、必要と感じたらどんどん入れていこう という話。

Prefer specialized functions, methods and constructors

読み手に意味を直接的に伝えられるメソッドを使おう という話。2

// BAD:
const EdgeInsets.TRBL(0.0, 8.0, 0.0, 8.0);

// GOOD:
const EdgeInsets.symmetric(horizontal: 8.0);

Have good hygiene when using temporary directories

一時ディレクトリはちゃんと管理しよう という話。

flutter_ で始まり、ピリオドで終わる一意の名前を付けよう(その後に自動生成されたランダムな文字列を続ける)。

あと、不要になったディレクトリはちゃんと綺麗に片付けること!
テストでは tryToDelete を使おう。3

Perform dirty checks in setters

セッターで Dirty チェックをしよう という話。

Dirty チェックというのは、変更された値がアプリの他の箇所と同期されているかをチェックすること。
例えば、セットのタイミングで Dirty であることをマーキングしておくにはこんな感じで書く。

TheType get theProperty => _theProperty;
TheType _theProperty;
void set theProperty(TheType value) {
  assert(value != null);
  if (_theProperty == value)
    return;
  _theProperty = value;
  markNeedsWhatever(); // the method to mark the object dirty
}

Common boilerplates for operator == and hashCode

operator ==hashCode をオーバーライドする時はこう書こう という話。

@override
bool operator ==(Object other) {
  if (other.runtimeType != runtimeType)
    return false;
  final Foo typedOther = other;
  return typedOther.bar == bar
      && typedOther.baz == baz
      && typedOther.quux == quux;
}

@override
int get hashCode => hashValues(bar, baz, quux);

オブジェクトがたくさんプロパティを持つなら、operator == を頭に置くことも検討しよう。

Override toString

toString をオーバーライドしてデバッグに使うよりも、Diagnosticable を使おう という話。
devtools や IDEでの調査も捗る。

Prefer naming the argument to a setter value

特に理由がない限りセッターの引数は value にしよう という話。

おわりに

driver test まわりの挙動に色々疑問があってソース追いかけていたのに、いつの間にか Style Guilde 読んでた...


  1. 中には analysis_options.yaml に書いておけばいいだけのものもあるので設定大事。 

  2. それっぽいメソッドが生えてないかドキュメントを逐次確認するのが大切ってことですね。 

  3. 例えばこんな感じにね! flutter_tools/test/integration/flutter_run_test.dart#L29 

17
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
5