【メモ】達人プログラマー

# はじめに
プログラマーの「考え方」を知りたいと思った為、達人プログラマーという書籍を購入しました。
いつ、どこでも見返せるようメモとして残します。

https://www.amazon.co.jp/%E9%81%94%E4%BA%BA%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9E%E3%83%BC-%E7%AC%AC2%E7%89%88-%E7%86%9F%E9%81%94%E3%81%AB%E5%90%91%E3%81%91%E3%81%9F%E3%81%82%E3%81%AA%E3%81%9F%E3%81%AE%E6%97%85-David-Thomas/dp/4274226298

# まえがき

## 誰が読むべき本なのか
- より効率的、そしてより生産的なプログラマーになりたい人

## 達人プログラマーになるためには
- 自らの技術に関心を持つこと 
- 自分自身がいま何をやっているのか、常に考え続ける必要がある
    - 絶対に漠然と仕事を進めてはいけない
    - 絶え間なく考え続け、リアルタイムで自らの作業を批判的に見るべき
- 継続は力なり


# 第１章　達人の哲学

## 常人と達人プログラマーとの違い
:::note
問題に対するアプローチとその解決手段についての考え方、スタイル、哲学である。
目の前の問題を考えるだけではなく、常にものごとの大局を見据える。
:::

## あなたの人生
<font color="Magenta">あなたには現状を打破する力がある</font>

## 猫がソースコードを食べちゃった
:::note
達人プログラマーは自分自身の経歴を管理し、無知や誤りを認めることを恐れない。
:::
- プロとして、可能な限りの対処を行うべく努力を重ねる
    - `自らの無知や過ちという欠点を素直に認めなければならない`
- `チーム内の信頼関係`が創造性とコラボレーションに欠かせない
- `責任を持つ`こと
    - 誰か・何かのせいにしてはいけない
    - すべて「あなた」の役割
        - ベンダーが要求に答えてくれないリスクがあるのなら代替計画を立てておくべき
        - ディスクがクラッシュした際にバックアップをとっていなかったら「あなた」のミス
    - 責任を負うことによって、怠慢によるプロジェクト崩壊を防ぐ
- いい加減な言い訳よりも`対策を用意する`こと
:::note
助けが必要であることを認めたり、要求することを恐れてはいけない
:::

:::note warn
「分からない」という言葉がつい出てきた時には、「でも答えを見つけ出すぞ」と口に出す。
:::
分からないと言うことを認める素晴らしい方法。そして、その後はプロとして責任を全うする。


## ソフトウェアのエントロピー

エントロピー：ある系における無秩序な度合いを表す指標

- `技術的負債`を放置しない
    - その負債は返済されず、無秩序に広がっていく可能性がある
- あらゆるネガティブな考え方は、チーム内に浸透していき、凶悪なスパイラルを生み出す
- プロジェクト開始時点での整合性を維持していく

:::note alert
悪い設計、誤った意思決定、質の低いコードをそのままにしてはいけない。
:::
発見と同時に全て修復する。
もしくは、その時間がないのであれば、分かりやすくその旨を明示しておく。


## 十分によいソフトウェア
- やめ時を知る
- 作り出したものが「十分に良い」かどうかを判断するためのプロセスに、ユーザーを参加させるのがオススメ
    - フィードバックによって、よりよい解決策へと導かれる場合もある
:::note alert
- ユーザーからの要求を無視して、プログラムに新機能を追加したり、コードをさらに磨き上げると言うのではプロフェッショナルとは言えない
- 不可能なスケジュールを約束したり、納期に間に合わせるために基本的な技術をおろそかにするのもプロフェッショナルとしてはあり得ない
:::

## あなたの知識のポートフォリオに対して定期的な投資を行うこと
- 定期的に投資する
    - `習慣`にする
    - 作業を`ルーティン化`する
- 多様化する
    - 作業で使っている特定技術のすべての詳細を知る必要がある
    - 今日の最新技術は、明日には使い物にならない（またはお呼びでない）ものになっている可能性もある
    - より多くの技術に親しむうちに、よりうまく`変化に適応`できるようになっていく
- 毎年少なくとも言語を一つ学習する
    - 言語が異なると、同じ問題でも違った解決方法が採用される
    - `いくつかの異なったアプローチを学習すれば、思考に幅が生まれる`
- 月に1冊のペースで技術書を読む
- 技術書以外の書籍を読む
- 講習を受講する
- 近場のユーザーグループに参加する
    - 孤立は避けるべき。社外の人たちがどういった仕事をしているのかを知るようにする
- 異なった環境に慣れ親しんでみる
    - Mac→Linaxにする、IDEをより良いものに変える等
- 最先端にとどまり続ける
    - 現在のプロジェクトが扱っているものとは異なるテクノロジーに関するニュースや投稿に目を通す
    - 他の人々がどういったことを経験しているのかを知る
- `継続し続けること`が肝要
- 貪欲に学習を続ける→最新技術について皆から質問を受ける→質問によっては大まかな答えしか出せない時もあるかもしれない（**ここで止まってはいけない**）→一般の人々向けのリソースではなく、学術的なリソースにも目を向ける→それでもだめなら答えられる人を探す（個人ネットワークの輪を広げる）

### 見聞きした物事を批判的な目で分析すること
- 「5つのなぜ」を問う
    - 誰にメリットがあるのか？
    - コンテキストは何か？
    - それはいつ、どこで有効になるのか？
        - 一次思考（次に何が起こるか）で立ち止まらず、二次思考（その後でなにが起こるか）を考えるようにする
    - なぜこれが問題なのか？

## 伝達しよう！
- 聞き手のことを知る
    - うまく聞き手に伝わった場合のみ伝達は成就される
        - そのためには、聞き手のニーズや興味、能力を理解しておく必要がある
        - コミュニケーションを取りながら、聞き手に関する知識を継続的に得る
- 言いたいことを知る
    - 「これで言いたいことの意味が聞き手に上手く伝わるだろうか？」と自分自身に問いかける
- タイミングを選ぶ
    - 「この話をする上で適切なタイミングかどうか？」を自問する
- スタイルを選ぶ
    - 「事実のみ」を好む人もいる
    - 聞き手のスキルレベルや経験に合った伝え方をする
- ドキュメントを作成する時の見栄えをよくする
    - 内容にのみ全精力を傾けてもだめ。Markdown記法など、見栄えをよくする方法は沢山ある
- 聞き手を巻き込む
    - フィードバックを受け、知恵を借りる
- 聞き手になる
    - 人に対して良い聞き手になってもらいたいのであれば、あなた自身も聞き手にならなければならない
- 相手の立場になる
    - 質問をしたが返ってこないからといって、無礼だと思ってはいけない
    - 相手がとても忙しいといったことなども考慮する
- ドキュメントとコードをまとめる
    - ドキュメントは付け足すものではなく、作り上げるもの
    - `達人プログラマーは、ドキュメントを開発プロセス全体とは切っても切り離せない重要なパーツだと考えている。`

## オンラインでのコミュニケーション
- [送信]ボタンを押す前に精読する
- フォーマットは簡潔で明確なものにする
- 引用は最小限にする
- 人を非難したり、煽ったりしない←自分に返ってくる
- 送信前に宛先を確認
- 投稿は永遠に残ることを意識する


# 第２章　達人のアプローチ

## 良い設計の本質
`ETC原則`（**Easier To Change** = 変更をしやすくする）

:::note
よい設計は、悪い設計よりも変更しやすい
:::

## DRY原則－二重化の過ち
`DRY原則`（**Don't Repeat Yourself** = 繰り返しを避けること）

:::note
システム内の二重化を最小限に抑えることを目的としている
:::

:::note warn
DRY原則を破るということは、同じ知識を2箇所以上に記述すること。
この場合、片方を変更するのであれば、もう片方も変更しなければいけなくなる。
:::

開発自体の理解とメンテナンスを容易にする唯一の方法は、DRY原則に従うこと。
「すべての知識はシステム内において単一、かつ明確な、そして信頼できる表現になっていなければならない」

:::note
既にあるものを簡単に見つけ出して再利用できるようにし、同じものを何度も作成しないような環境を構築すること
:::

こちらに例を記載しました。

https://qiita.com/reraise/items/bb6ddaca199b6fe0cea4


## 直交性

:::note
システムのコンポーネント間の依存関係を最小限に抑えることを目的としている
:::

`関係のないもの同士の影響を排除する`
- 生産性の向上
    - 変更が局所化されるため、開発期間とテスト期間が短縮される
    - 再利用性の促進
- リスクの低減
    - コード中の問題発生部分を隔離できるようになる
    - システムがより堅牢になる
    - コンポーネント単位の設計やテストが簡単→検証しやすい
- コードを記述する度に、アプリケーションの直行性を低下させるリスクが発生
    - コードの結合度を最小化する必要がある
    - `グローバル変数`を避ける
        - コード内でグローバル変数にアクセスする度に、そのコードはデータを共有しているその他のコンポーネントと結び付けられる。グローバル変数は、例え参照しかしていない場合であっても問題につながる可能性がある（急遽、コードをマルチスレッド化する必要が出てきた場合等）
    - `Singletonパターン`（特定クラスのインスタンスをただ一つだけに制限するためのもの）も、グローバル変数としてしようする人が多いため注意が必要
    - 擬似機能を避ける
:::note
直交性を念頭において設計、実装されたシステムは、テストが簡単になる
:::

## 可逆性
- 変更があった場合に、簡単に戻せるような柔軟で適合性の高いソフトウェアを生み出す
    - `DRY原則`、`分離`、`外部設定`の使用を貫き通せば、後戻りが許されない多くの重大な意思決定から解放される
- 「コードの柔軟性」と同時に、アーキテクチャーやデプロイ、ベンダー統合という切り口からも柔軟性を維持する必要がある

## 曳光弾
目標を見つけるには曳光弾を使う。
- 早いうちからユーザーにものを提示できる
    - 上手く伝達できれば、ユーザーからのフィードバックも期待できる
- 常にデモを行える環境がある
- 進捗が明確になる

### プロトタイピング
システムの最終形態が持つ特定の側面を追求する為のもの
実際のプロトタイピングでは、コンセプトの確認を終えた後、作成したものを全て捨て去り、得られた教訓を基にもう一度正しい形で再構築していく。

:::note
プロトタイピングは使い捨てのコードを生成する。
曳光弾は使い捨てではない。曳光弾によるコードは最小限度のものだが完全なものであり、最終的なシステムの骨格を構成するもの。
:::

序盤の部分のみ