フロントエンドでとても大切な3つのプラクティス

# はじめに
令和になりましたので、フロントエンドに関する腑に落ちている有用なプラクティスを3つ程共有しようと思います。 

※ 意見等はコメント欄ではなく、直接編集リクエストでください

## 1. フロントエンド参入時期に通る迷いの道
フロントエンドで例えば、Vue.js、React等を学習する人は一度はこう思うと思います。
とりあえずライブラリの使い方わかったけど、コンポーネントはどう書けば良いとされているのかな？
そういえばFluxって流行っているけどなんだろう？
Vuex、Reduxってなんだろう？使ったほうがいいのかな！
SPA、Prerender、SSRってどれがいいのかな。
どう使えば良いのかな？
それらを簡単に判断できるようになる為の原則と、とある症状を紹介しようと思います。

## YAGNIの原則とセカンドシステム症候群
これは凄く大切な原則です。

### YAGNIの原則
まずはYAGNIです。
[Wiki引用](https://ja.wikipedia.org/wiki/YAGNI)です

> "You ain't gonna need it"、縮めて YAGNI とは、機能は実際に必要となるまでは追加しないのがよいとする、エクストリーム・プログラミングにおける原則である。

> 理由
YAGNI原則を提唱する人々は、その理由として以下を挙げている。

> 後で使うだろうという予測の元に作ったものは、実際には10%程度しか使われない。したがって、それに費やした時間の90%は無駄になる。
余計な機能があると、仕事が遅くなり、リソースを浪費する。
予期しない変更に対しては、設計を単純にすることが備えとなる。そして、必要以上の機能を追加すると、設計が複雑になってしまう。
人生の時間は、貴重である。したがって、人間の能力は、ただコードを書くためではなく、現実の問題に集中するために使うべきである。
結局は、その機能は必要ないかもしれない。もしそうなったら、あなたがその機能を実装するのに費やした時間も、他のみんながそれを読むのに費やした時間も、その機能が占めていたスペースも、すべて無駄になってしまうだろう。
コードをすばやく実装するために最も良い方法は、あまりコードを書かないことである。そして、バグを減らすために最も良い方法も、あまりコードを書かないことである。

つまり、今絶対に必要なコードだけで行こうぜって事です。
言い方変えてもう一度言うと、恐らく必要になるだろうという過剰な対策をするのをやめ、今必要な事なコードだけを書いていく事です。

以下の記事はわかりやすい、典型的な盛り過ぎな良い例だと思います。
**[テスト駆動開発とマイクロサービスのせいで短命に終わったスマホゲームの話
](https://tech.nikkeibp.co.jp/atcl/nxt/column/18/00620/040900010/)**

### セカンドシステム症候群
**[人月の神話](https://www.amazon.co.jp/exec/obidos/ASIN/4621066080/gixo-22/ref=nosim/)**で登場する、"[セカンドシステム症候群](https://ja.wikipedia.org/wiki/%E4%BA%BA%E6%9C%88%E3%81%AE%E7%A5%9E%E8%A9%B1#%E3%82%BB%E3%82%AB%E3%83%B3%E3%83%89%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E7%97%87%E5%80%99%E7%BE%A4%EF%BC%88%E7%AC%AC%E4%BA%94%E7%AB%A0%EF%BC%89)"も、YAGNIと言い方は違いますが似たような事を言っています。

[Wiki引用](https://ja.wikipedia.org/wiki/%E4%BA%BA%E6%9C%88%E3%81%AE%E7%A5%9E%E8%A9%B1#%E3%82%BB%E3%82%AB%E3%83%B3%E3%83%89%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E7%97%87%E5%80%99%E7%BE%A4%EF%BC%88%E7%AC%AC%E4%BA%94%E7%AB%A0%EF%BC%89)
> セカンドシステムは、人間が設計したものの中で、最も危険である。なぜなら、作り込みすぎてしまうというのが、一般的な傾向だからである。

例え以前色々あっても、2回目のシステムこそYAGNIの原則を守りたいものです。
ちなみに自分もセカンドシステム症候群は1度経験した事があり、今ではとても深く反省しています😓

## 攻略 "フロントエンド参入時期に通る迷いの道"
我々はこれらの原則や反省を活かすべきです。
あなたは今ReactやVueのコンポーネントシステムで何か問題を抱えているのでしょうか？
単一状態木が本当に必要状況なのでしょうか？

Redux の作者、Dan Abramovさんもこう言っています。(引用
> Flux ライブラリは眼鏡のようなものです: それらが必要になったときに知るのです。

つまり、VueやReactでの開発で現状特に問題を感じていないのでしたら、それを続けるべきです。
もし今のコードに自信が持てないようでしたら、「[リーダブルコード](https://www.amazon.co.jp/%E3%83%AA%E3%83%BC%E3%83%80%E3%83%96%E3%83%AB%E3%82%B3%E3%83%BC%E3%83%89-%E2%80%95%E3%82%88%E3%82%8A%E8%89%AF%E3%81%84%E3%82%B3%E3%83%BC%E3%83%89%E3%82%92%E6%9B%B8%E3%81%8F%E3%81%9F%E3%82%81%E3%81%AE%E3%82%B7%E3%83%B3%E3%83%97%E3%83%AB%E3%81%A7%E5%AE%9F%E8%B7%B5%E7%9A%84%E3%81%AA%E3%83%86%E3%82%AF%E3%83%8B%E3%83%83%E3%82%AF-Theory-practice-Boswell/dp/4873115655)」を読んだり、「[アルゴリズムとデータ構造](https://www.amazon.co.jp/%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E3%82%B3%E3%83%B3%E3%83%86%E3%82%B9%E3%83%88%E6%94%BB%E7%95%A5%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AE%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0%E3%81%A8%E3%83%87%E3%83%BC%E3%82%BF%E6%A7%8B%E9%80%A0-%E6%B8%A1%E9%83%A8-%E6%9C%89%E9%9A%86/dp/4839952957/ref=sr_1_1?adgrpid=59027707171&gclid=Cj0KCQjw2v7mBRC1ARIsAAiw3481TpLn79LTa53ueP4UmRunpSnBXYz1i8BMRc41SxBOsgneNqGn3jAaAv-9EALw_wcB&hvadid=338568233726&hvdev=c&hvlocphy=1009300&hvnetw=g&hvpos=1t1&hvqmt=e&hvrand=10478152719728839186&hvtargid=kwd-332424084896&hydadcr=27265_11561133&jp-ad-ap=0&keywords=%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0%E3%81%A8%E3%83%87%E3%83%BC%E3%82%BF%E6%A7%8B%E9%80%A0&qid=1558191895&s=gateway&sr=8-1)」を読んで鍛えたり、Scala等の関数型プログラミングの世界を体験し、自身のレベルアップを図る方が良いかもしれません。

もしあなたが本当にFluxライブラリが必要になったら、あなたにググり力さえあればきっと、「これだー！」って出くわすはずです。
もしかしたその時が来たらもっと筋の良い新たなライブラリかFluxに変わる新たなパターンがあなたが抱えていた問題をもっと上手く解決している可能性もありますね。

SPA、SSRもPrefetchもそうです。
本当に必要になったらそれらと出会うでしょう。
私の場合は部分的にPrefetchし、SPAで開発するのが最も開発しやすくて、生産できているので、きっとそれが今の私のベスト構成なのでしょう。


## 2. フロントエンドのコンポーネントの粒度
私はフロントエンドのコンポーネント粒度は[この「Atomic Components」](https://qiita.com/kahirokunn/items/b599d2cf04d2580c412c)を強く推しています。
その理由は、現在のフロントエンド環境で一番しっくりくる設計だからです。
ではAtomic Componentsで実装する際に、よく聞かれる上から作ればいいのか、下から作ればいいのかについて軽く説明をします。

### トップダウンでコンポーネントを作っていく
これは、デザインチームがAtomic Designを採用していない場合です。
もし複数箇所で同一のコンポーネントが登場した場合等々、切り出しが必要なケースに遭遇したら切り出していけばいいです。
特に何も迷うことなく今まで通りの実装していきましょう。

### ボトムアップでコンポーネントを作っていく
これは、デザインチームがAtomic Designを採用している場合です。
デザインチームがAtomic Designを採用している場合ならデザインチームの粒度通りに実装すれば良いでしょう。

## 3. コンポーネント間のやりとりに関して
YAGNIばかり言っても面白くない人もいると思いますので、コンポーネント間のやりとりを疎結合にしたVue.jsで書いたサンプルを紹介します。
このテクを一部の複雑なコンポーネントの隔離に使うと、それの実装に無理があってもリファクタリングや作り直しがしやすくなります。 例: KANBAN等...
必要な場面で使ってくれると嬉しいです。

### 一応ざっくりと疎結合にした際のメリット
* テストがしやすい。
* 修正しやすい。
* 交換しやすい。
* 影響範囲の限定。
* 場合によっては生産性が上がる
* 人によるけど、慣れると実装がめっちゃ早い。
* etc...

### ざっくりと疎結合にする際のデメリット
* 何を元にして、結合度を決めるのかの判断と共有が必要。
* コード量の増加。
* 自身・チームメンバー含めある程度の技量を追加で要求してしまう。
* 場合によっては生産性が下がる
* 場合によってはチームをただただ混乱させるだけになる。
* etc...

### サンプル
今回は疎結合な実装のサンプルの1つとして、素直なコンポーネント同士が連携する様子を紹介します。

以下がサンプルgifです。
[![Image from Gyazo](https://i.gyazo.com/f3faa4342a0d547ccc35c0f6d94adcd6.gif)](https://gyazo.com/f3faa4342a0d547ccc35c0f6d94adcd6)

ソースコードはこちらにあります。 (注意: 色々と魔改造しているのは気にしないでください。
https://github.com/kahirokunn/book-management

特徴
* ハンバーガーメニューをクリックしたらナビゲーションメニューが開く
* ユーザーアイコンをクリックしたらプロフィール編集画面が開く

実現方法

![0001.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141711/fdd533a3-eb51-7fe2-6902-cc71cbf1bff7.jpeg)

ある程度の凝集度を確保しつつ、必要なければ親子関係を作らず、フラットに配置できるようにしています。
コンポーネント同士の連携はメッセージを介してやりとりするようにしています。
そして、作成した各種コンポーネントをページやレイアウト等で適当に配置して動作させてます。
実際にイベントを発行しているヘッダーのコードは[こちら](https://github.com/kahirokunn/book-management/blob/a0de8681369655ae26f5910d50ec5f4bb1ba0e14/src/components/containers/loggedInHeader.vue#L57)です。
また、イベントを待ち受けているDialog式のプロフィール編集フォームのコードは[こちら](https://github.com/kahirokunn/book-management/blob/a0de8681369655ae26f5910d50ec5f4bb1ba0e14/src/store/containers/changeUserProfileForm/action.ts#L8)で、そのコンポーネントのコードは[こちら](https://github.com/kahirokunn/book-management/blob/master/src/components/containers/changeUserProfileForm.vue)です。

なんとなく雰囲気でこんな感じにやればいいんだーって見て取れたら幸いです。

## 最後に
書いてる途中で力付きてしまい、最後は少し雑になりましたが如何だったでしょうか。
実は今回メインはYAGNIの話で、後ろの2つのプラクティスはおまけです笑
フロントエンドの開発は中々判断が難しい部分もありますが、頑張っていきましょう！