Java 経験者がやりそうなスタイルガイド違反

Dart と Java は似ているところあるけれど、そのままの気分で書くと、公式スタイルガイドぶっちぎることがままある。大体は DartEditor が見つけてくれるんだけど、DartEditor も見つけてくれない類のスタイルガイド違反がいくつかあったので、自分が引っかかったところをメモ。

* [Dart Style Guide | Dart: Structured web apps](https://www.dartlang.org/articles/style-guide/)

[`final` 変数は lowerCamelCase](https://www.dartlang.org/articles/style-guide/#do-name-constants-using-allcapswithunderscores)
=======================================

Dart での厳密な意味での定数は `const` 修飾子がついた変数であり、`final` が付いた変数は一度だけセットできる変数というニュアンスらしい。（きちんとした性質の違いの説明は [Final and Const](https://www.dartlang.org/docs/dart-up-and-running/contents/ch02.html#ch02-final-const) を参照）

このことからか、const 修飾子の変数のみが `ALL_CAPS_WITH_UNDERSCORES` という名前を付けること、それ以外は、たとえ`final`修飾子が付いていても、`lowerCamelCase` で付ける。

良い:

> ```dart
> const PI = 3.14;
> const DEFAULT_TIMEOUT = 1000;
> final urlScheme = new RegExp('^([a-z]+):');
>
> class Dice {
>   static final numberGenerator = new Random();
> }
> ```
> [Dart Style Guide | Dart: Structured web apps](https://www.dartlang.org/articles/style-guide/#avoid-creating-classes-that-contain-only-static-members) から

ダメ:

> ```dart
> const pi = 3.14;
> const kDefaultTimeout = 1000;
> final URL_SCHEME = new RegExp('^([a-z]+):');
>
> class Dice {
>   static final NUMBER_GENERATOR = new Random();
> }
> ```
> [Dart Style Guide | Dart: Structured web apps](https://www.dartlang.org/articles/style-guide/#avoid-creating-classes-that-contain-only-static-members) から

関係ないけど `const` 使える条件厳しくてあんまり使えてないのでまだ dart 力足りてないのかもしれない。

[`class *Utils` みたいな静的メソッド集やめろ](https://www.dartlang.org/articles/style-guide/#avoid-creating-classes-that-contain-only-static-members)
=============================================

引っかかったわけでは無いけど、事前に core ソース読まなかったら作ってただろうなーということで書く。

Java だと状態を持たないしあちこちで使うヘルパー関数みたいなものを作りたいとき、`class *Utils` や `class *s` (java.lang とか guava) って関連する名前のクラスを作って、静的メソッドとしてぶら下げることをよくやるのですが、Dart はそのまま関数定義できるので、そちらを使いましょう。

良い:
> ```dart
> library utils;
> 
> num distance(num x1, num y1, num x2, num y2) {
>   /* ... */
> }
> ```
> [Dart Style Guide | Dart: Structured web apps](https://www.dartlang.org/articles/style-guide/#avoid-creating-classes-that-contain-only-static-members) から

ダメ:
> ```dart
> library utils;
> 
> class GeometryUtils {
>   static num distance(num x1, num y1, num x2, num y2) {
>     /* ... */
>   }
> }
> ```
> [Dart Style Guide | Dart: Structured web apps](https://www.dartlang.org/articles/style-guide/#avoid-creating-classes-that-contain-only-static-members) から

「`distance` って名前被りそうこわい」って時は、`distance` を定義した `utils.dart` を接頭辞付きでインポートする:

```dart:名前衝突を回避する
import 'utils.dart' as utils;

main() {
  /* ... */
  final d = utils.distance(x1, y1, x2, y2);
  /* ... */
}
```

Dart は mix-in できるので、そちらも選択肢としてあります。

[新たなインスタンス作るのに静的メソッド使うのやめろ](https://www.dartlang.org/articles/style-guide/#do-use-constructors-instead-of-static-methods-to-create-instances)
=============================================

代わりに名前付きコンストラクタで定義する:

良い:
> ```dart
> class Point {
>   num x, y;
>   Point(this.x, this.y);
>   Point.zero()
>       : x = 0,
>         y = 0;
> }
> ```
> [Dart Style Guide | Dart: Structured web apps](https://www.dartlang.org/articles/style-guide/#avoid-creating-classes-that-contain-only-static-members) から

ダメ:
> ```dart
> class Point {
>   num x, y;
>   Point(this.x, this.y);
>   static Point zero() => new Point(0, 0);
> }
> ```
> [Dart Style Guide | Dart: Structured web apps](https://www.dartlang.org/articles/style-guide/#avoid-creating-classes-that-contain-only-static-members) から

こうすることで「`new` が頭に付く文は新しいインスタンスを作る文だ」ということが分かりやすくなります。（インスタンスメソッドでも新しいインスタンス作るケースあるしこの主張はどうなんだろう。）

`new` した直後に初期化したかったり、インスタンスの初期化に複雑な処理だったりするときは `factory` 修飾子つきのコンストラクタを使う:

```dart
class Point {
  num x, y;
  Point();
  factory Point.zero() {
    final p = new Point();
    p
      ..x = 0
      ..y = 0;
    return p;
  }
}
```

ただ、この `factory` 修飾子つきコンストラクタは、`null` やシングルトンなインスタンスも返せてしまうので使い方に注意する必要がある。つまり `new ...` って書いてあるのに `null` やシングルトンインスタンスが
返っていくるという罠っぽい挙動になってしまう。

他に Java のつもりで書いていたらこんなのに引っかかった！みたいな話を募集中です。ひょっとしたら私が書いているかもしれないので。