Javaでコードを書くときに意識していること

# 前置き
普段はJavaを書いているので、Javaを想定して書きます。
DDDっぽい趣向が入ってしまうのをなんとか避けつつ...(願望)

## 略称を使わず、総称を使う
例に関して、`id` ですら `identifier` と書いてしまう筆者なので少し過剰気味かもしれませんが、短く意味が伝わらない名前より、長くて意味が伝わる名前の方が良いと思います。理想は短く伝わること(できるなら1語)です、より理想に近い名前づけを意識すると良いかと思います。(`i` や `id` などデファクトスタンダードな名前に関しては例外)

```.java
class Identifier {
  String value;

  Identifier(String value) {
    this.value = value;
  }

  String value() {
    return value;
  }
}
```

## 出来るだけ独自型を使用する
`String` や `int` など言語にすでにある型は独自アプリケーションの概念を表現するには向いていないように感じます。よく変数などで命名して表現**しようとしている**コードを見ますが、変更が起きた場合にIDEの力を借りての変更ですら「変更忘れ」「Typo」など面倒なだけの作業になりかねません。また独自に型を定義することで得られるメリットは、**引数を渡す際にコンパイルエラーになってくれる**、**プロダクトコード内に同じ概念のオブジェクトが別で定義されない(再利用)**、など出来るだけ型で表現してみるのがいいと思います。

```.java
class Name {
  String value;

  Name(String value) {
    this.value = value;
  }

  String value() {
    return value;
  }
}
```

## 名前が思いつかないときはわざと変な名前をつける
よく「こんなクラス名でPR上がってるのなぜ？」と言われるんですが、そう思わせたらほぼ思惑通りです。目指しているのは誰もが引っかかる違和感です。あとで変更する意図を名前に含めておくことで戒めのような活躍も**変な名前**はしてくれます。**それっぽい名前**をつけてしまうと、見向きもされずに腐っていくのがオチという体験を繰り返して私はこう書いています。本番にマージするには勇気がいりますが、よくよく考えてみてください。**それっぽい名前**、**それっぽい処理**が、この**変な名前**以外に絶対ないと言い切れますか？またそれを明確に見つけられる手段はあるのですか？と考えればそれほど抵抗は無くなります。一番大事なことですが最後にはしっかり名前をつけてことが、**変な名前**をつけた責任です。

```.java
// TODO 言葉を見つけられた時に修正する
class XxxCharacter {
  String value;

  XxxCharacter(String value) {
    this.value = value;
  }

  String value() {
    return value;
  }
}
```

## 区分はとりあえずEnumで列挙してみる
**趣味**です。ある程度思考停止してます、と言いつつ区分にできるものは業務処理の分岐などになりやすく、区分による処理の違いを押し込めやすいため**とりあえず定義**してみます。合わなければ多分区分にするほどでもなかったと割り切って独自クラスとしてそれぞれ宣言するか、別の何かを考えます。

```.java
enum Gender {
  NONE, MALE, FEMALE
}
```

## 業務ロジック(ビジネスルール)はモデルに持たせるように心がける
業務ロジックはレイヤー分けされた中の`Service層`などに良く散見されます。私が思うに`Service層`は**業務**を書く層で、**ロジックを定義する層ではない**と思っています。あるべき層に書くとしたら` Domain層`に書きます。理由はいたってシンプルで、業務の関心ごとを詰め込んだ層だからです。私は業務の関心ごとの事を業務ロジックと思っています(勘違いかも)。ちなみにDRYも守れていいね！という観点も嬉しいです。

```.java
class Age {
  int value;

  Age(int value) {
    this.value = value;
  }

  int value() {
    return value;
  }

  boolean isMinor() {
    return value < 20
  }
}
```

## 完全コンストラクタでインスタンス生成する
**不変**を意識しています。インスタンス生成時にオブジェクトの責務を限定し、**内部の状態が変更されない**ことを保証したいためです。`Setter` を書かないことも関連してきます。可変を許容しやすいコードを書くと**誰かにどこかで知らぬ間に変更されている！**という状況を与えてしまい「コードを読む、テストをする、デバッグをする」等の作業の時に見なければいけないコードの量も増えていきます。見る箇所は最小限かつ状態定義する場所は一つの方がいいですよね？常に同じ状態が返ってくるということで、前述のようなことが起きないのはプロダクトが大きくなるにつれ、とても幸せだと感じるようになると思います。何気なく`Setter`でクラスの状態を定義しようとした時は踏みとどまってみるのもいいかもしれませんね。厳密には`final`修飾子を付与し更に強固にしたほうがという意見ももらうのですが、プロダクトに関わるチームのレベル感によって合わせています。**こんな使い方する人いないだろう**をある程度信じて私は`final`修飾子を書くことが少ないです、何より書くのが面倒なので。もっとよく知りたい人は**完全コンストラクタパターン**で調べてみてください。

```.java
class User {
  Identifier identifier;
  Name name;
  Age age;
  XxxCharacter xxxCharacter
  Gender gender;

  User(Identifier identifier, Name name, Age age, XxxCharacter xxxCharacter, Gender gender) {
    this.identifier = identifier;
    this.name = name;
    this.age = age;
    this.xxxCharacter = xxxCharacter;
    this.gender = gender;
  }
}
```

## 前がかりとしてstaticメソッドでインスタンス生成する
インスタンス生成に名前をつけることで抽象度が高いクラスの責務を定義します。**抽象度の低い別クラスにするか**の指標や、ある**カテゴリ違い**によるインスタンス生成を行う場合に使用してます。お決まりごととしては、コンストラクタを`private`にするのをお忘れなく。でないと自由度が増してしまい想定外の状態を持つクラスが誕生してしまうことになるので。ちなみに理由なく何でもかんでも`static`にしていると**staticおじさん**といって嘲笑されかねないので気をつけてください。

```.java
class User {
  Identifier identifier;
  Name name;
  Age age;
  XxxCharacter xxxCharacter
  Gender gender;

  static User ofMale(Identifier identifier, Name name, Age age, XxxCharacter xxxCharacter,) {
    return new User(identifier, name, age, xxxCharacter, Gender.MALE);
  }

  static User ofFemale(Identifier identifier, Name name, Age age, XxxCharacter xxxCharacter,) {
    return new User(identifier, name, age, xxxCharacter, Gender.FEMAL);
  }

  private User(Identifier identifier, Name name, Age age, XxxCharacter xxxCharacter, Gender gender) {
    this.identifier = identifier;
    this.name = name;
    this.age = age;
    this.xxxCharacter = xxxCharacter;
    this.gender = gender;
  }
}
```

## ループ処理の雑な使い分け
Javaでループする場合は主に、`stream`か`for`を使用してます。
私が使い分けする雑な指標として、**例外を投げない、あるオブジェクトからあるオブジェクトを生成するなどの時は`stream`**、**例外を投げる、voidのメソッドを順次呼ぶだけなどの時はfor**を使用しています。`stream`はメソッドチェーンで書けてオブジェクトに対する中間操作など複雑になりがちな処理をシンプルに見れるので個人的には好きです。一方`for`はブロック内で直前の処理にあまり影響しないようなコードを書くときに使用します。あと例外が`stream`より扱いやすいので。

## util系のモジュールを作りそうになった時は踏みとどまってみる
`util`、`manager`、`helper`など役目が広すぎて神になってしまうモジュールのことですね。「便利なツールってないかなぁ」や「変更の時大変やし、とりあえず重複避けたろ」というときに良く作られる傾向です。特に後者は変更がきた場合に、使用している片方だけに影響があるパターンが多いです。これをDRYとしてドヤられても困るなんてことは良くありました。良く考えてみてください、言葉通り**神**なので愚かな人類が扱える代物ではないのです。むしろ人が生み出す神なんて**合成魔獣**でしかないんです。疾う疾う成仏するべし。

## コードをコメントで説明しようとした場合は、踏みとどまる
悪気はないはず...のやつです。コードのすぐ近くにありコード以上の情報を与えない、謎規則による謎フォーマットの価値がない、多分あげればたくさんあるのですが、あまりいいものではないかもしれません。コメントはコンパイルが通りません、間違っていてもコンパイラは教えてくれないので負債になりやすいです。コードは動くので間違っていれば指摘がありますし、IDEの力を借りればリファクタもやりやすいと思っています。私がコメントを書く際に考えるのは二つありまして、**このコメントは善意になりうるか悪意になりうるか**、**これを書くまえにコードで表現できないか**です。コメントが悪だとは思いませんが、道具は使うものによって道生(その後)を決められます。真摯に向き合ってみるのがいいのではと感じることが多いです。

## テストコードにおいてはテストメソッド名は日本語で書いてコード内にコメント等を書いてみる
すぐ上で書いたのに、コメント書くんかい！と思われるかもしれません。しかしテストコードにはプロダクトコードと違い、決まった流れがあることは少なく実装者に委ねられることが多いので私的感情や論理が入り混じる書物になります。だとすれば説明の責任を取ろうという気持ちが私は強くなります。あ、関係ないですが**テストは仕様書！**と良く耳にしますが、果たしてそうなのでしょうか？と疑心暗鬼になる毎日です。


# まとめ
今後も追加していく予定です。マサカリが怖いので**私は**と強く強調しています。ですが、良い悪い関わらずご意見あればよろしくお願いします。