今回読んだ本
達人プログラマー新装版
本の印象
この本はプログラマーであるけれど、これ以上先に進むにはどうすれば良いか、よく詰まること、陳腐化することってあるよね、そういうときにどうすればよいかを記した本です。
例えば割れ窓理論という話があります。家の窓が割れていたらどうしますか?当たり前ですが修理しますよね。逆に修理を放置したらどうなるでしょうか。誰も何もしなければそれは不良学校のような荒れた場所になります。
これはソースコードでも一緒です。100人規模で開発してると汚いところはわかっているけれど、放置するなんてことはザラにあります。段々と荒れ果てた地になっていくので、なるべく早く窓を修理してしまいましょう。
以下、気になったところをどんどん書いていきます。
ソフトウェアの哲学編
十分に良いソフトウェア
ソフトウェアには不良は必ずある。が、そこまで神経質になる必要はなく、90%のユーザが満足すればそれでよい。残りの10%を追い求めようとすると生産性は下がる。
知識ポートフォリオ
IT分野の進化のスピードは凄まじい。今ある技術もいつか陳腐化することを前提でいること。バナナや野球のチケットのようなもの。
ポートフォリオの管理ポイント
- 定期的な投資
- 分散投資
- 堅実な投資とハイリスク投資のバランス
- 定期的に見直して再分配を行う
知識ポートフォリオは金融ポートフォリオと似ている
設計のアプローチ編
良い設計の本質
良い設計とは悪い設計よりも変更しやすい。ETC原則(EasyToChange)
- 結合を単一化する
- 名前の付け方を深考する
良い設計をするための習慣
設計時の状況を日誌に残し、選択肢と変更時の前提を残し振り返りを行う
DRY原則は基本的に守る、時には破る
ログ表示などlowレベルなレイヤーは二重化されるべきで、highレベルなコントローラーレイヤーは二重化するべきではない。validate処理などは似ているように見えて要求仕様が一緒であるだけ。変化する可能性がある。
直交性
コンピューティング分野では独立していない、結合度の低い場合直交しているといえる。
直交していることの利点
依存度の高いシステムの場合、局所的な修正では済まない。
関係のないコンポーネントの影響を受けない
生産性の向上
- 変更の局所化で開発期間とテスト工数が短縮
- 新機能は新しいコードの追加となり既存コードの変更が不要
- A機能、B機能が直行していれば AxBの機能が実現できるが、直交していなければ(依存してれば)機能重複するのでAxBよりも必然的に少なくなる
リスクの低減
- 障害時、改修時影響範囲が小さい
- 検証が容易い
コーディング
- コードの結合度を最小化する
- デメテルの法則
- グローバル変数を避ける
- Singletonパターン(1つのクラスインスタンスのみ制限するパターンだが、多くの人はグローバル変数的な使い方をするので注意)
- 類似機能を避ける
- 共通コードが最初と最後にあるなどよくある話
- コードの二重化を避けるデザインパターンとしてStrategyパターンを参考にする
可逆性
エンジニアは与えられた課題に対して、簡潔なたった一つの解決策を好む。
何かを実装する場合解決策は複数個あり、ベンダーやビジネス状況により3個にも5個にもなり得る。変更されないシステムなどない。
例えばAデータベースを開発を進めているとして、開発終盤に明らかにBデータベースよりも遅いことがわかってしまった場合、データベース永続化部分だけ抽象化できていれば、いつでも交換できる、可逆性のあるシステムだと言える。
Webアプリではなくてモバイルアプリが欲しいとビジネス側に要求されたら?APIだけ切り出せていればそこまで手戻りは少なくなるはずである。
プロトタイピングで勘違いすること
プロトタイピングはあくまで使い捨てのプロダクトということが関係者全員が理解できていないとプロジェクトが進んだときに勘違いする。
そのプロトタイピングに魅せられたマネージャーが「これで行こう!」と勘違いしてしまうことが往々にしてあり、あくまで使い捨てなので工数は別でかかることを共通認識でいる必要がある。
内部ドメイン言語と外部ドメイン言語
内部
言語特有の記述方法であったり、Ruby RSpecなどの書き方など
外部
AnsibleやOpenAPIなど JSON, YAML, CSVなどで構成できる言語のこと。
一般的にこれらの言語の方が可逆性は高いと言える。
見積り
見積もりの伝え方。15日の場合は15日かかると伝える。10週かかる場合は 3ヶ月と伝える
- 1~15日 ⇒ 日
- 3~8週 ⇒ 週
- 8~20週 ⇒ 月
- 20週超え ⇒ 大きすぎるので提出する前に再考するか、分割する
見積りはどこから来るのか
- 一番の秘訣は過去に似たようなことをした人にどのくらいかかるか聞く
- それがMaxである
- 過去のチケットと比べる
PERT手法(Program Evaluation and Review Technique)
- タスクに対して楽観時間、最確時間、最悪時間を算出する
見積り精度をあげるには
見積もり精度の振り返りを行い、どのくらい誤りがあったか毎回測定をする
何回も繰り返して精度を上げていくこと。似たような案件は必ずあるため、事例の調査をする。
エンジニアツール編
エディター
vimを使いこなそう!!(本著には記載されていません。。。w個人の見解です。)
毎日1時間かかる作業を10%効率を上げると月で5時間も浮くことになる。
まずはチャレンジ
- オートリピートを使わずにブロック選択して削除
- マウス、トラックパッドを使わない生活を1週間行う
- 統合できる場所を探す
- Pluginを探す、もしくは自作する
デバッグ時の思考法
- バグが起きたときのスタックトレースを2分探索法で行うことを癖付ける
- 上から順になめると O (N), 2分探索であれば O(log n)となる
- ログを真ん中あたりでまずは見る、上下でバグがあるレイヤーを探し更に2分探索して見つけ出す
- リリース時の障害探索でも同じ方法が使える
ラバーダッキング
まずは人に話すと話すために思考整理するため、勝手に問題解決につながる
思考実験
- PCにコーヒーをぶちまけたとする
- 会社に新しいパソコンの申請をし、新しいパソコンがくる
- PCのセットアップ、元の状態に戻すまでどのくらいかかるか、嫌な顔をされるかを想像する
リソースのバランス方法
どんな言語でもメモリーの開放を意識してプログラミングしたほうが良い。
CやC++はなおのこと、Javaなどのガーベッジコレクションで管理されてるものであれば、GCの動きを意識したほうが良い。
Javaでよくオブジェクト使用後にNullを設定することがあるが、それはGCにリソース開放を長い目で見たときに効率より早くしてもらうためである
ヘッドライトの先を越さない
車のヘッドライトの照射距離は約50m、対して時速60kmでの停止距離は58m、時速110kmだと140mだそう。ヘッドライトの先を越すことはそんなに難しくない。
つまり小さく進んだほうが停止距離内なので安全である
柳に雪折れなし
コードに柳のような柔らかさ、柔軟性をもたせれば雪(外部要因)で折れることはない
- Observerパターン
- PubSubパターン
- リアクティブプログラミング(RxJS, webflux)
- 継承は悪。インタフェースはOK
- 継承が答えになることは滅多にない
- 外部設定でアプリケーションをコントロールする
- Config as a Service
- 設定を外部に切り出しアプリケーション事に変更、変更時に通知できるようにすれば柔軟性のある設計になる
コーディング段階
テストはバグを発見するものではない。設計、APIや結合の観点を得るためである。
テストの利点はテストについて考えテストを作り出してる時に生み出される(テストファースト)
地雷原を渡るような偶発的プログラミングはやめよう。
リファクタリング
リファクタリングと機能追加を同時に行ってはいけない
リファクタリング前にテストを用意すること。何回も実行すること
名前の変更はかなり難しい。名前はすぐに誤解を呼ぶ名前をつけてしまう。
例えば getData というメソッドからデータを保存する処理も同時にしていたなどあり得る話です。
プロジェクトを始める前に
相談者はプログラムを読めるわけではない。要件定義書はBiz側とDev側の差を埋めるものであり、より詳細な仕様を書いても意味がない。
協働する
ペアプログラミング、モブプログラミングは会議よりも良い方法です。コードを書く中で議論をしてより良いコードを書く方法です。
読んだ感想
感想
意外と書いてあることは人間的なコミュニケーションが主体でした。ソフトウェアは人が作るものなので人を知ることも重要であるというのがわかりました。
プログラマーとして生きていくのにポートフォリオの話などまさに参考になったと思います。毎年1言語覚えるのが理想であると書いてあり、まさにだなぁと感じました。
読むべき対象者
- ある程度実務経験をしているプログラマー
- 話の内容が抽象的な部分が多いため、経験をしていないと具体的に想像できないことがある
- プログラム言語を学ぶというより、プログラムの哲学を学ぶための書なので、具体的な解決策を望んでいる場合にはおすすめできない
- 今やってる方法でよいのかどうか確認や実務経験でやったことを体系的に思い出す際に読むと良いです。
今回読んだ本
もう少しレベルが高いのを期待する場合はこちらの新装版をおすすめ