Yuta NakataのBlog

Python / AWS / ITについて役立つ情報を発信します

達人プログラマーのTipsまとめ

先日、達人プログラマー第2版を読みました。

新卒2年目(ソフトウェア開発5年目)として、目から鱗の金言が多かったので、Tipsを一覧にしてまとめました。

また、ダウンロードできるように以下にPDF版も載せておきます。

https://drive.google.com/file/d/1AgMZLnKpdQcDWtAa-vdBIG9xNSZYsHXa/view?usp=drive_link

これを機に、世界的な名著を読まれることをオススメします!

1. 自らの技術に関心を持つこと
ソフトウェア開発をうまく進めようという心を持たずして、自らの人生をソフトウェア開発に費やそうとするなかれ。

2. あなたの仕事について考えること!
漫然と仕事を進めるのではなく、自ら制御権を掌握すること。そして、常に批判的な目で自らの作業を評価すること。

3.  あなたには現状を打破する力がある
これはあなたの人生についての話である。しっかりと手綱を握り、自らが望むように進めていくこと。

4.  いい加減な言い訳よりも対策を用意すること
言い訳ではなく対策を用意する。「できない」などと言わずに「できる」ことを明確にする

5.  割れた窓を放置しておかないこと
まずい設計、誤った意思決定、貧弱なコードを見つけたら修正する。

6.  変化の触媒たれ
他人に変革を強制することはできない。そうではなく、未来を垣間見せ、その実現に参加できるよう手助けする。

7.  大きな構想を忘れないようにすること
詳細に入り込みすぎて、周囲の状況をおろそかにしてしまわないようにする。

8.  品質要求を明確にすること
ユーザーを巻き込み、プロジェクトの真の品質要求を決定する。

9.  あなたの知識ポートフォリオに対して定期的な投資を行うこと
学習の習慣をつける

10. 見聞きしたものごとを批判的な目で分析すること
ベンダーの売り文句、メディアの宣伝、独善的考えに惑わされない。あなたとあなたのプロジェクトという観点から情報を分析する。

11.  日本語をもうひとつのプログラミング言語として考えること
日本語をもうひとつのプログラミング言語として考え、コーディングを行うようにドキュメントを記述する。DRY原則、ETC、自動化などを順守する。

12.  伝えることがらと、伝える方法は車の両輪だと考えること
うまく伝えることができなければ、よいアイディアも無意味である。

13.  ドキュメントは付け足すものではなく、作り上げるものである。
コードと別に作られたドキュメントは、正確性に劣り、すぐに陳腐化する。

14.  よい設計は悪い設計よりも変更しやすい
ものごとはそれを使う人に適応できる場合にうまく設計されていると言える。コードの場合、それは変化に対応できなければならないということを意味している。

15.  DRY - Don’t Repeat Yourself(繰り返しを避けること)
システム中の全ての知識は、重複なく、明瞭、信頼できる表現となっていなければならない。

16.  再利用しやすいようにしておくこと
再利用しやすくしておけば、皆はそれを使うためにやってくる。再利用をサポートできる環境を構築する。

17.  関係のないもの同士の影響を排除すること
単一目的のうまく定義され、自己完結した独立コンポーネントを設計する。

18.  最終決定などというものは存在しない
石に刻みこまれたような決定はあり得ない。全ての決定を砂浜に描かれたものと考え、変更に備えていく。

19.  流行を追い求めないようにする
Neal Fordの言葉、「昨日のベストプラクティスは明日のアンチパターンになる」を噛み締め、流行ではなく、地に足のついたアーキテクチャを選ぶこと

20.  目標を見つけるには曳光弾を使うこと
曳光弾を使えば、目標の補足と目標にどれだけ近く着弾したのかが判るようになる。

21.  プロトタイプの真の目的は学びにある
プロトタイプとは、学習の経験についてである。その価値は出来上がったコードではなく、学習した教訓そのものになる。

22.  問題領域に近いところでプログラミングを行うこと
問題領域の言葉で設計、コーディングを行う。

23.  後でびっくりしないために、見積もりで行うこと
始める前に見積もりを行い、前もって潜在的な問題を洗い出しておく。

24. 規律に従ってスケジュールを繰り返し、精度を向上させていくこと。
プロジェクトの期間見積もりに磨きを掛けるには、その実装によって得た経験を用いる。

25.  知識はプレインテキストに保存すること
プレインテキストは、廃れることなく、デバッグやテストを簡潔にする強力な武器となり得る。

26.  コマンドシェルの力を使うこと
GUIで実現できなければシェルを使う。

27.  エディターに熟達すること
エディターは最も重要なツールである。やりたいことを迅速かつ正確に実現できる方法を知っておく必要がある。

28.  常にバージョン管理システムを使用すること
バージョン管理システムはあなたの仕事で使えるタイムマシンであり、どんな過去にも戻ることができる。

29.  避難するのではなく、問題を修復すること
バグの原因が誰にあるかは問題ではないーー問題はあなたのものであり、あなたが解決しなければならないのだ。

30.  パニクるな
銀河のヒッチハイカーと開発者はこの言葉を忘れてはいけない。

31.  コード修正の前にテストを失敗すること
バグの修正に取り掛かる前に、そのバグを再現するテストを作成すること。

32.  エラーメッセージをちゃんと読む
ほとんどの例外メッセージには、どこでどういったことが発生しているのかも含まれる。運が良ければ、パラメータの値も表示されている。


33.  “select”は壊れていない
OSやコンパイラ、さらにはサードパーティの製品やライブラリのバグを見つけることは稀である。バグはたいていの場合アプリケーション側に存在する

34.  仮定を置かずに、証明すること
実際の環境ーつまり実際のデータと境界条件を用いて仮定を証明する

35.  テキスト操作言語を学ぶこと
毎日多くの時間をテキスト作業にさいているのなら、そういった作業をコンピュータにさせるべきである。

36.  あなたは完璧なソフトウェアを作ることができない
ソフトウェアは完璧にならない。このため、不可避のエラーからコードとユーザーを守る。

37.  契約を用いて設計を行うこと
ドキュメントには契約の考え方を用い、コードがそれ以上のこともそれ以下のことも行わないようにする。

38.  早めにクラッシュさせること
中途半端に動いているプログラムは、停止したプログラムよりもたちが悪い。

39.  もし起こり得ないというのであれば、表明を用いてそれを保証すること
仮定を検証するには表明を使用する。表明を用いて不確かな世界からコードを守る。

40.  始めたことは終わらせる
リソースの開放は、可能な限りそのリソースを割り当てた関数やオブジェクトが責任を持って行うべきである。

41.  ものごとを局所的にする
変更可能な変数のスコープを制限し、リソースの使用時間を短くするとともに可視化できるようにしておくこと。

42.  少しずつ進めること ー 常に
常に小さな歩幅で少しずつ進める。そしてフィードバックを得た上で、先に進む前に軌道修正を加える。

43.  予言は避ける
見えるところまでのみを見るようにする。

44.  分離されたコードは変更しやすい
ものごとを結合させると、1つのことを修正するのも難しくなる。

45.  照会せずに依頼する(TDA : Tell, Don’t Ask)
オブジェクトから値を取得し、その値を操作し、結果をオブジェクトに戻してはいけない。該当オブジェクトにすべての仕事を任せること。

46.  メソッド呼び出しを連鎖させないこと
何かにアクセスする際には、ドット(..)を2つ以上続けないこと。

47.  大域データを避ける
これはすべてのメソッドにパラメーターを追加して回るのと同じ結果になる。

48.  大域データにするだけ重要なものである場合、APIでラップする。
….とは言うものの、どうしても大域データにしておきたい場合にのみこの手を選択すること。

49.  プログラミングとはコードについての話であるが、プログラムはデータについての話である
全てのプログラムはデータを変換し、入力を出力へと変える。まず、変換を用いた設計を考えること。

50.  状態をため込まず、引き渡すようにする
関数やモジュール内にデータをため込まずに、引き渡すようにすること。

51. インヘリタンス(相続)税を払わないこと
インターフェースや委譲、mixinといったニーズに見合った代替策を考慮すること。

52.  ポリモーフィズムの表現にはインターフェースを愛用すること
インターフェースは、継承によって生み出されるような結合を気にすることなくポリモーフィズムを実現できる。

53.  サービスに委譲すること:has-a は is-aに勝る
サービスを継承してはならない。サービスを保持するようにすること。

54.  機能の共有にはmixinを使用する
mixinを使えば、相続税を支払うことなくクラスに機能を追加できるようになる。インターフェースと組み合わせて、痛みを伴わないポリモーフィズムを実現すること。

55.  外部設計を用いてアプリをパラメーターに対応させる
アプリケーションが本番稼働に入った後でも、ある程度挙動を変えられるようにするには、アプリの外側でそういった挙動を指示する値を保持しておく。

56.  並行性を向上させるためにワークフローを分析する
ユーザーのワークフローにおける並行性を明らかにする。

57.  共有状態は間違った状態
状態の共有によって全てをやり直すしかないほどの様々な問題が生み出される。

58.  無秩序なエラーはしばしば並行処理によって引き起こされる
並行処理のバグは、タイミングやコンテキストの変化によって無秩序かつ再現性のないかたちで引き起こされる。

59.  共有状態を持たないアクターを並行処理で使用する
明示的な動機を用いずに並行処理を管理するにはアクターを使用する。

60.  ワークフローを協調させるためにはホワイトボードというコンセプトを活用すること
独立性を保ったまま共通点のない事実やエージェントを協調させるには、ホワイトボードを使用する

61.  爬虫類脳に耳を傾ける
開発中のコードが抵抗しているように感じられるのは、あなたの無意識が何らかの間違いを訴えかけているためである。

62.  偶発的プログラミングを行わないこと
信頼のおけるもののみを信頼する。偶発的な複雑さを避け、単なる偶然と意図的な結果を混乱しないようにする。

63.  アルゴリズムのオーダーを見積もること
どのくらいリソースを消費するのか、コードを書き始める前に感触をつかむようにする。

64.  見積もりの検証を行うこと
アルゴリズムの数学的分析で全てが分かるわけではない。このため、対象としている環境で実際に測定する。


65.  早めにリファクタリングすること、そしてこまめにリファクタリングすること
庭の雑草取りや植物の植え替えと同じように、必要に応じてコードの再記述、再作業、再アーキテクトを行う。そして問題の根本原因を修正する。

66.  テストとはバグを見つけることではない
テストとは、コードに対する1つの観点であり、その設計やAPI、結合についてのフィードバッグを与えてくれるものである。

67.  テストはコードのユーザー第1号である
テストからのフィードバックを活用し、要求に対する洞察を深めること。

68.  トップダウンでもなくボトムアップでもなく、エンドツーエンドで構築していく
エンドツーエンドで小さな機能を構築し、そこから作業を進めながら問題について学習していく

69.  テスト設計を行うこと
コードの記述を始める前にテストのことを考え始める。

70.  ソフトウェアをテストすること、さもなければユーザーにテスト強いることになる
容赦ないテストを行う。ユーザーが先にバグを見つけることのないようにする。

71.  仮定を検証するためにプロパティベースのテストを使用すること
プロパティベースのテストは、あなたが試してみようと思ったことのないテストを試し、想定されていない方法でコードを実行してくれる。

72.  KISSの原則を守り、アタックサーフェスを最小化する
複雑なコードやバグは、攻撃に利用できる脆弱性の温床となる。

73.  セキュリティパッチはすぐに適用すること
攻撃者はすぐに攻撃を仕掛けることができるため、それよりも先に手を打つ必要がある。

74.  適切な名前を付け、必要に応じてリネームすること
読み手に意図を理解してもらえる名前を付け、意図が変わったのではあればすぐにリネームすること。

75.  自らが欲しているものを正確に認識している人などいない
全体的な方向性はわかっているかもしれないが、その先に待ち構えている紆余曲折など誰も知らない。

76.  プログラマーの仕事は、人々自身が欲しているものを自らで気付いてもらえるように支援すること
ソフトウェア開発とは、ユーザーとプログラマーによる共同開発という行為である。

77.  要求はフィードバッグループの中で学んでいくものとなる
要求を理解するには、探求とフィードバックが必要となり、意思決定の積み重ねが初期のアイディアを洗練する鍵となる。

78.  ユーザーとともに働き、ユーザーのように考える
これがシステムの「実際の使用法」について洞察を得る最善の手である

79.  ポリシーはメタデータである
ポリシーをシステム内にハードコーディングしてはいけない。ポリシーはシステムによって使用されるメタデータとして表現すること。

80.  プロジェクトの用語集を作ること
プロジェクトが使用する特定の専門用語や語彙をまとめた用語集を作成、維持する。

81.  枠に囚われずに考えるのではなく、枠を見つけ出すこと
不可能と思える問題に遭遇した場合、「本当の制約」を見抜く。「この手段でやり遂げなければならないのか?」「そもそもやらなければならないのか?」を自問する。

82.  一人ぼっちでコーディングに取り組んではいけない
プログラミングは要求水準の高い難しい作業である。このため仲間を連れて行くように。

83.  Agileという言葉は名詞ではなく、ものごとの進め方を形容する形容詞である
「Agile」は何かを実行するあなたのスタイルを指す形容詞である。

84.  小規模で安定したチームを作ること
チームはメンバー全員がお互いのことをよく知っており、信頼し合い、助け合う、小規模で安定したものとなっているべきである。

85.  事を成し遂げるにはまずスケジュールする
スケジュールしなければ何ごとも怒らない。振り返りや実験、学習、スキルの向上をスケジュールする。

86.  完璧に機能するチームを編成すること
チームの編成は、職務権限ではなく機能に基づいて実施すること。ユーザーインターフェースとユーザーエクスペリエンスのデザイナーとコーダーを、フロントエンドとバックエンドを、テスターとデータモデラーを、設計と配備を分離してはいけない。コードをエンドツーエンドで構築でき、インクリメンタルかつイテレーティブに開発できるチームを編成すること。

87.  流行を追いかけるのではなく、効き目がある物事を実行すること
他社が実践しているというだけの理由で開発手法や開発テクニックを採用してはいけない。あなたのコンテキストで、あなたのチームに有効なものを採用すること。

88.  ユーザーが必要としたタイミングで調達すること
採用しているプロセスを理由にして、何週間も、あるいは何ヶ月も調達を遅らせてはいけない。

89.  バージョン管理によってビルド/テスト/リリースを駆動すること
コミットやプッシュを使用してビルドやテスト、リリースを起動する。本番環境への配備を実行するためにバージョン管理タグを使用する。

90.  早めにテスト、何度もテスト、自動でテスト
毎回ビルドを行うたびに実行されるテストは、棚にしまわれているテスト計画書よりもずっと有効なものとなる。

91.  テストが全て終わるまでコーディングは終わらない
これ以上の説明は要らないはず。

92.  テストのテストをするには破壊工作を試みる
テストがうまく機能するかどうかを確認するには、目的に応じたバグをソースのコピーを混入してみる。

93.  コードのカバレージではなく、状態のカバレージをテストをすること
テストは、重要なプログラム状態を識別して行う。全ての行をテストしただけでは十分ではない。

94.  同種のバグを一度に見つけること
テスト担当者がバグを見つけた場合、今後はもうそのバグ自体を人間が見つけることのないようにする。以降は自動化されたテストにチェックさせる。

95.  手作業を排除する
コンピューターであれば、同じ命令を同じ順序で何度も実行できる


96.  単にコードを調達するのではなく、ユーザーを喜ばせる
業務価値を生み出すソリューションをユーザーのために生み出し、彼らを日々喜ばせる。

97.  あなたの作品に署名すること
先人たちが自らの成果物に誇りを持って署名したように、ソフトウェアに署名する。

98.  とにかく、害をなさないようにすること
問題の発生を避けられない。誰も問題によって苦しまないようにすること。

99.  極悪なことを実行できるようにしない
さもなければ自らも極悪な人間になるリスクを負うことになる。

100.  これはあなたの人生だ。皆と共有し、祝福し、生み出していくこと。そして思いっきり楽しむこと!
素晴らしい人生を楽しみ、偉大な成果を成し遂げよう。