プログラム初心者向けー知って得するベストプラクティス・原則・パターン集

# はじめに

TIS Advent Calendar 2019の2日目の記事です。初心者向けに何か書こうと思います。

簡単に言うと、初心者の方なら数年は持つベストプラクティスやパターンを上げているサイトを列挙しました。
（もし中級者の方が見られる場合は、知らない単語のリンクへ飛んで一覧だけ見ておくとよいでしょう）

ベストプラクティスを知らないエンジニアと、存在を知っており適切に使えるエンジニアでは物凄い差が生まれます。

キャリアをプログラマからスタートする前提で、実装寄りのものから、アーキテクチャ設計、システム連携、クラウドと並べていきます。
私はアーキテクトという肩書なので、その傾向がリストに出ていますが、どこかでキャリアが分かれる場合は必要なところまでを知っておけば十分だと思います。

最後のほうに学習方法についても触れておきます。

## 覚えきれないことを知る＆早めにベストプラクティスを手に入れる
普段あまり絡みはないですが、エンジニアの学習について、新人さんや初心者さんやエンジニア希望者に伝えていることが２つあります。
１．人間の記憶力には限界がある
２．なるべく最先端に行ってそこで戦う

まず、１の人間の記憶力についてですが、「[マジカルナンバー](https://ja.wikipedia.org/wiki/%E8%A8%98%E6%86%B6)」という考え方があります。
> 一般に成人における短期記憶の容量は、7±2（5から9まで）程度と言われている[3]。この仮説は心理学者のジョージ・ミラーが提示したものであり、7±2という数はマジカルナンバー (magical number) と言う。このマジカルナンバーは、まとまりのある意味のかたまりである「チャンク」という単位で示される  

何か新しいことを覚えようとしても、容量に限りがあるので、「短期記憶」で覚えることは効率よくする必要があります。

良く言われている対策や工夫は、以下のようなことです。

* 丸暗記に使わない
* インデックスか検索できるワードを覚える
* 外部記憶（だいたいGoogle先生）を使う

次に２の最先端に関してですが、「[車輪の再発明](https://ja.wikipedia.org/wiki/%E8%BB%8A%E8%BC%AA%E3%81%AE%E5%86%8D%E7%99%BA%E6%98%8E)」という言葉があります。
>  「広く受け入れられ確立されている技術や解決法を知らずに（または意図的に無視して）、同様のものを再び一から作ること」

車輪の再発明自体は、個人的には好きではないですが、否定はしません。時にはあえて再発明する状況もあるかもしれません。実際、学習のために同じスペックのプログラムを別の言語で作ることもします。ものすごく短時間ですが。

エンジニアの人生は短いので、「車輪」の存在を「知らない」ことは、圧倒的な不利益となりえるため否定しておきます。
車輪を1つ再発明することに時間を使うより、同じ時間を使って他の車輪の存在を100個知ることのほうが有益なものになります。

もし、なるべく最先端で仕事をしたいのなら、何かを調べたり方法に悩む際に、「best practice」「pattern」をつけて検索したりし、最先端のやり方や答えを探す癖をつけましょう。
もし答えがないなら最先端に近いです。

# ベストプラクティス・原則・パターン集
★を３つまでで知っておいてほしい度を表しておきます。また、括弧で数を書いておきます。

## プログラミングの原則やパターン
ここに上げるものは、古典的なものばかりですが、早く知っておくに越したことはないです。

### SOLIDの原則(5), パッケージングの原則(3+3)　★★★
プログラミングの、クラス設計の原則とパッケージ（クラスの集まり）の原則です。
SOLIDは5つの頭文字から来ています。コードを書く上で常に使うのでぜひ学びましょう。

* SOLID
    * https://ja.wikipedia.org/wiki/SOLID
* Robert C. Martin の Principles of OOD  
    * http://objectclub.jp/community/memorial/homepage3.nifty.com/masarl/article/oo-principles.html

### GRAPS Pattern(9) ★★
プログラミングする上での、クラスや役割の分類学と原則です。全部で9つあります。  
覚えると何ができるか、ですが、コードを読むときに、ちゃんとしたコードなら「設計」の原則で分類できるので、「これはデータエキスパート、これはコントローラー、これはクリエーター」などと素早く解析できるようになります。

* 第2回 うまくデザインパターンを使うための心得
    * https://www.atmarkit.co.jp/fdotnet/designptn/designptn02/designptn02_02.html
* 【中級】基礎からのオブジェクト指向 第5部 「GRASPパターン」を理解する
    * https://tech.nikkeibp.co.jp/it/article/COLUMN/20060607/240196/

### BCE分析(3) ★
Boundary, Control, Entityの略です。これは1つのシステムを設計する際にクラス構成を描くときに使います。

* ロバストネス図を活用したシステム設計
    * https://thinkit.co.jp/article/13487

### UML図(7+7) ☆
書く必要に迫られるまでは、存在していることを知っておくくらいでよいかと。
* UML
    * https://ja.wikipedia.org/wiki/%E7%B5%B1%E4%B8%80%E3%83%A2%E3%83%87%E3%83%AA%E3%83%B3%E3%82%B0%E8%A8%80%E8%AA%9E

### その他の原則 ★
DRYの原則、YAGNIの原則、KISSの原則、Hollywoodの原則、 IoCなど。ググりましょう。

* YAGNI。無駄なものを作ることによる４つのコストを知りましょう。
    * https://martinfowler.com/bliki/Yagni.html

## 実装のデザインパターン ☆
現代においてGoFの23のデザインパターンを新たに写経レベルで学ぶ必要は感じません。当時の言語の機能不足と呼べるものです。
並行性のパターンはさらっと目を通しておきましょう。

* Design pattern(23)/Concurrency pattern(13)/...
    * https://en.wikipedia.org/wiki/Software_design_pattern
* その他を知っておくと良いもの
    * Double Dispatch パターン
        * https://www.infoq.com/jp/articles/DoubleDispatch_0829/
    * Generation Gapパターン - 自動生成コードを改修する場合など
        * http://www.hyuki.com/dp/dpinfo.html#GenerationGap
    * Null Object パターン
        * https://thinkit.co.jp/article/926/1?page=0%2C1

## UIのアーキテクチャ　★★★
2サイトにある7パターンです。
MVC（基本）、MVVM（C#など）、Flux（Reactなどのフロントエンドで使用）くらいは押さえておきましょう。

* 開発者が知っておくべき、6つのUIアーキテクチャ・パターン
    * https://www.atmarkit.co.jp/fdotnet/chushin/greatblogentry_10/greatblogentry_10_01.html
* Fluxアーキテクチャ（Redux、Vuexなどのアーキテクチャ）
    * https://facebook.github.io/flux/docs/in-depth-overview

## アプリケーション設計 ★★★
全部で51パターンありますが、３分の一くらいは、ORマッピングに関するものでしょうか。
書籍が有名です。日本語版は訳語に癖があります。

* Enterprise Application Architecute pattern(51)
    * http://bliki-ja.github.io/pofeaa/CatalogOfPofEAA_Ja/
    * (英語) https://martinfowler.com/eaaCatalog/

## システム間連携 ★
複数のシステムを開発する場合に参考にします。これも書籍が出ています。
アプリケーションパターンが終わるころに手を出すとよいと思います。

* （英語）Enterprise Integration pattern(65)
    * https://www.enterpriseintegrationpatterns.com/patterns/messaging/

## SQL アンチパターン(25+1) ★★
バックエンド開発する場合は知っておくと良いでしょう。
日本語訳された書籍が出ていますが、翻訳者のスライドシェアもあります。

* SQLアンチパターン 
    * https://www.slideshare.net/t_wada/sql-antipatterns-digest
* SQLアンチパターン幻の26章
    * https://www.slideshare.net/t_wada/ronsakucasual

## UI/UXの原則 ★★★
UI/UXの研究では、ヤコブ・ニールセンという方がとても有名です。
Webか、モバイルか、ディスクトップかで変わってきますが、基本的な5原則は把握しておきましょう。
MicrosoftやGoogleがフリーのガイドラインを出しているのでそちらも参考に。

以下のリンクの最初のまとめサイトから飛ぶのが良いです。

* UI/UXデザイナーなら一度は目を通しておきたい「デザイン原則」まとめ
    * https://uxxinspiration.com/2014/02/design-principles/
* 基礎知識！ZとFの法則
    * https://blog.maromaro.co.jp/archives/2256
* Nielsen Norman Group
    * (英語) https://www.nngroup.com/articles/
* Windows ユーザー エクスペリエンス ガイドライン
    * https://docs.microsoft.com/ja-jp/windows/apps/desktop/
* Google UXガイドライン
    * https://developers.google.com/web/fundamentals/design-and-ux/ux-basics

## Cloud/Microservieの設計パターン ★★
クラウドでのアプリケーションで有名な原則はTwelve Factor Appというものがあります。

* Twelve-Factor App （日本語）
    * https://12factor.net/ja/
* Beyond the Twelve-Factor App
    * https://content.pivotal.io/blog/beyond-the-twelve-factor-app

Cloudのアプリケーションを開発する上でのガイドラインです。
これも日本語でMicrosoftやGoogleがオンラインガイドを出しています。

* クラウド設計パターン: Using Microsoft Azure
    * https://docs.microsoft.com/ja-jp/azure/architecture/patterns/
* ハイブリッドおよびマルチクラウドのアーキテクチャ パターン (Google)
    * https://cloud.google.com/solutions/hybrid-and-multi-cloud-architecture-patterns?hl=ja

Microserviceの設計パターンですが、英語の書籍とサイトがあります。どちらも同じクリスリチャードソンという作者です。

* （英語）A pattern language for microservices
    * https://microservices.io/patterns/index.html
* （英語書籍）Microservices Patterns: With examples in Java 
    * https://www.amazon.com/Microservices-Patterns-examples-Chris-Richardson/dp/1617294543

# 学習方法について

## 最初の学習

エンジニアとしての学習のコツ的なものを。（できるできないは個人差があります）

* 楽しみながら好きなことをやらないと続きません。

```
学生でないので無理、苦行、修行をしてはいけません。
できるだけ仕事と方向性を合わせると良いでしょう。
Will、Can、Should、Doはすべて違うので、あまりに違う場合は転職しましょう。
```

* 速度を優先し、トライする回数を増やします。

```
タスクを行う際に、予実と復習を行います。
タスクはとにかく小さく設定し1-2時間程度にしておきましょう。
調査などの不明なタスクは、投資時間（タイムボックス）を決めて作業しましょう。
1. どんなタスクにも時間を設定しておき、予実を計測します。（人には言う必要はありません）
2. 予定はきつめに設定しますが、最後に20-30％をバッファを必ず足しておきましょう。（精神衛生の向上）
3. 終わったタスクは必ず、「頭の中だけ」でもう一度再実行して、どの程度で終わるかを計算します。
    - たとえば、プログラミングの場合、トライ&エラーなどやトラブルシューティングは除き、今の知識ですべてを最適な順で再実行した場合どうなるかを頭の中だけで行っておきます。
    - 体で再現できないタスクは投資した意味がないです。必ず復習を設定しておきましょう。
    - 「頭の中だけ」ですることで、高速に、かつ、記憶できる量だけ重要な要素を抽出して整理できます。
```

* Googleの検索能力を高めましょう。

```
- 英語のページを必ず入れます。日本語だけで行くと見つからない答えが見つかります。
    - 「とは？」系は、「what is」「overview」をつけます。
    - ナレッジ系は、「best」「best way」「best practice」をつけます。
    - トラブル系は、「not work」をつけます。
    - StackOverflowなどのQAでは、ベストアンサーと「thank」「work」で検索し解決策があるかを探します
```

* （できれば）速読を覚えましょう。人生の速度に差がつきます。

```
少なくとも脳内での活字のナレーション（仮想の音読的行為）をやめましょう。
  - 日本語。ひらがなはほとんど、修飾語はすべて落としてよいです。
  - 英語。文法に注目し、主語、述語、目的語だけ見ます。修飾語は落としてよいです。
  - 良い文章は、見出しがしっかりしており、段落の先頭にサマリがあるのでそれだけ見ても成立します。
  - 悪い文章は、読まないでも良いことが多いです。
```
本もサイトも流し読みを行い、重要な場合は回数を増やしましょう。
記憶は限度があるので、1週間かけて１回だけ読んだ本は覚えられません。
たとえば、同じ1週間でも、3回、しかも期間を開けて読めばその間知識も増え、吸収率も増します。

* プログラミング言語やフレームワークの実践経験。

```
- 最初のプログラミング言語は丁寧に覚えるとよいでしょう。
- 2つ以上は覚えたほうがキャリアは広がります。
- 増やす場合は1-2年で1つくらいをめどに増やしましょう。
```

## 英語について

エンジニアなら、覚えて損はないです。
特に検索時に英語を入れないとトラブルシューティングでは泣かされます。
なるべく初心者の時から、慣れましょう。

英語は覚え方もありますが、また今度にでも書きたいと思います。
（英語を覚えると、アメリカに住みこみで働くことになったり、12/2の投稿を時差計算ミスって4連休の最後の日に無理やり書いたりする場合もあります）