カロリーゼロ食品から思い浮かべるもの ~暗黙的な概念は伝わらない~

# はじめに
変なタイトルですみません。

言いたいことはカロリーゼロ食品の味がどうこうではなく、 **暗黙的な概念は伝わらないので、重要な概念は明示的に表現すべき** ということ。

**動くソフトウェアではなく、動き続けるソフトウェアを作るため** には、重要な概念をきちんと表現すべきだと思っている。

# 普通の食品とカロリーゼロ食品の違い
私は普段カロリーゼロ食品を食べないので正確な違いはわからず、「味が違うんだろう」「ダイエットに向いているのではないか」くらいなことしか思い浮かばない。しかし [実は恐ろしいゼロカロリーの秘密](http://mdpr.jp/diet/detail/1489607) という記事を読むと、他にも以下のような違いがあることがわかる。

 * 太りやすい体質になる。

 * 味覚が鈍化する。

他にも違いがあるが省略する。ここではその違いの真偽や良し悪しについて言いたいわけではない。主張したいことは **「カロリーゼロ食品」という単語から、そういった暗黙的な違いを全て汲み取ることができるのか？** ということ。私には無理。

# ソフトウェア開発の現場では
ソフトウェア開発の現場でも同じようなことが起こっている。例えば新入社員や他部署からの異動者に、アプリケーションの振る舞いを正確に伝えるドキュメントがあるだろうか。私の経験ではそんなドキュメントは存在しない。理由は様々だろうが、私の現場では以下のような理由からである。

 * ドキュメントに書かなくてもレビュー時に口頭で説明できればレビュー合格とする文化のため、ドキュメント作成者がドキュメントに書くべき内容を意図的に省く。

 * 評価時に出た不具合の修正内容をドキュメントに反映しないため、ドキュメントとコードの内容に差異が生じる。

それならドキュメントなんか信用せず、コードを見れば良いじゃないかと思うかもしれない。しかしそのような現場ではコードでも重要なことは表現されていない。

例えば下記のような、運送料を計算するコードを考える（ [C#実践開発手法](http://www.amazon.co.jp/%EF%BC%A3%EF%BC%83%E5%AE%9F%E8%B7%B5%E9%96%8B%E7%99%BA%E6%89%8B%E6%B3%95-%E3%83%9E%E3%82%A4%E3%82%AF%E3%83%AD%E3%82%BD%E3%83%95%E3%83%88%E5%85%AC%E5%BC%8F%E8%A7%A3%E8%AA%AC%E6%9B%B8-Gary-McLean-Hall/dp/4822298477/ref=sr_1_1?ie=UTF8&qid=1445169193&sr=8-1&keywords=C%23%E5%AE%9F%E8%B7%B5%E9%96%8B%E7%99%BA%E6%89%8B%E6%B3%95) から引用 ）。

```sample.cpp
class Size { /* ... */ };
class RegionInfo { /* ... */ };

int calculateShippingCost(
        float packageWeightInKilograms,
        const Size& packageDimensionsInInches,
        const RegionInfo& destination)
{
    // 運送料を計算する処理
}
```

運送料を計算するアプリケーションで重要と思われる概念（重量、金額）が ```float``` 型、 ```int``` 型になっていることで、以下のような問題が生じる。

 * ```Size``` や ```RegionInfo``` と ```float``` や ```int``` のレベルが揃っていなくて気持ち悪い。

 * 重量や運送料は負の値を取らないはずなので ```calculateShippingCost``` に事前条件と事後条件を追加する必要があり、運送料を計算するロジックが埋もれてしまう。

 * ```calculateShippingCost``` 以外にも重量や金額を扱う箇所で値の検証をする処理を記述しなくてはいけない。

これは ```Weight``` と ```Money``` 型を導入すれば解決する。

# では、どうしたら良いのか

 * 重要な概念などはコードで伝える

   設計とはコードがどのように振る舞うかを規定したものであり、それはコードで表現するものだ（アプリケーションは仕様書の記載通りに動作するわけではない）。コードで記述するものをドキュメントでも記述するのは時間の無駄だと思う。それよりは振る舞いの背景にある意図など、コードで記述できないことを補うためにドキュメントを利用する方が良い。

 * 一度で完璧な設計をしようとしない

   [PHPカンファレンス2015PHPメンターズセミナー「モデルをお設計せよ!-ドメイン駆動設計を超えて」](https://phpmentors.doorkeeper.jp/events/31453) の発表で **実装力 = 全てを切り拓く力** とあったが、その通りだと思う。設計とコーディングを分けて考えるのではなく、ドメインモデルを設計しながら実装／実装しながら設計を実践することでより良い設計に近づけるのではないかと思っている（こういう考えを **ドメインコーディング** と呼ぶらしい）。

 * いろいろな視点を持つ

   一枚の写真や一つのニュース記事などから受ける感想は各個人異なる。これは各個人が異なる視点で物事を見ているためだ。様々な視点で物事を見ることができれば、暗黙的な概念を引き出すことができるかもしれない。PHPカンファレンス2015PHPメンターズセミナーの発表では、 **もし〇〇だったらどうか** という風に様々な仮定を設定すると今まで見えなかったことが見えるようになるかも...とのアドバイスがあった。

# まとめ

 * 自分の意図していることを正確に伝えることは難しいので、伝えたいことは明示的に表現すべき。

 * 相手の主張したいことを掴むために、様々な視点を持つべき。

# 参考

 * [C#実践開発手法](http://www.amazon.co.jp/%EF%BC%A3%EF%BC%83%E5%AE%9F%E8%B7%B5%E9%96%8B%E7%99%BA%E6%89%8B%E6%B3%95-%E3%83%9E%E3%82%A4%E3%82%AF%E3%83%AD%E3%82%BD%E3%83%95%E3%83%88%E5%85%AC%E5%BC%8F%E8%A7%A3%E8%AA%AC%E6%9B%B8-Gary-McLean-Hall/dp/4822298477/ref=sr_1_1?ie=UTF8&qid=1445169193&sr=8-1&keywords=C%23%E5%AE%9F%E8%B7%B5%E9%96%8B%E7%99%BA%E6%89%8B%E6%B3%95)
 * [エリック・エヴァンスのドメイン駆動設計](http://www.amazon.co.jp/%E3%82%A8%E3%83%AA%E3%83%83%E3%82%AF%E3%83%BB%E3%82%A8%E3%83%B4%E3%82%A1%E3%83%B3%E3%82%B9%E3%81%AE%E3%83%89%E3%83%A1%E3%82%A4%E3%83%B3%E9%A7%86%E5%8B%95%E8%A8%AD%E8%A8%88-Architects%E2%80%99Archive-%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2%E9%96%8B%E7%99%BA%E3%81%AE%E5%AE%9F%E8%B7%B5-%E3%82%A8%E3%83%AA%E3%83%83%E3%82%AF%E3%83%BB%E3%82%A8%E3%83%B4%E3%82%A1%E3%83%B3%E3%82%B9/dp/4798121967/ref=sr_1_2?ie=UTF8&qid=1445169283&sr=8-2&keywords=%E3%83%89%E3%83%A1%E3%82%A4%E3%83%B3%E9%A7%86%E5%8B%95)
 * [PHPカンファレンス2015PHPメンターズセミナー「モデルをお設計せよ!-ドメイン駆動設計を超えて」参加レポート](http://phpmentors.jp/post/131193847968/phpcon2015-phpmentors-workshop-design-models-beyond-ddd)