読者です 読者をやめる 読者になる 読者になる

エンターテイメント!!

遊戯王好きのJavaエンジニアのブログ。バーニングソウルを会得する特訓中。

【書評】プリンシプル・オブ・プログラミング

勉強 書評

読むに至った背景

パラパラ捲って見たが、既知の内容を幅広く集約しているようだった。
既に読了済みの本の内容を多くまとめている感じがしていて、買うか迷ったが、複数の本と合わせて読むことが一冊である程度できるので購入。
目的としては、いろいろ読んだ本の知識を、個の本を読むことで繋いで知識を体系化したい。

内容と考察

内容+個人の考えを載せている。
この記事=本の内容ではないので、注意

前提

プログラミング・ソフトウェア開発には、変わらない真実がある。 真実を見たい場合、真実の扉の先に行かなければならない。
扉の向こうに行くには、通行料として、長時間の苦痛・苦悩が必要になる。

真理を by ハラグロハイイロクマ on pixiv

プログラミングに銀の弾丸はない

プログラミングに特効薬はない。
これを使えば、どんな問題も解決できるものはない。
なぜなら、ソフトウェアは本質的に複雑であるため。(人間関係と一緒)
問題にぶち当たったら、歴史から戦う術を探してみる。

コードは設計書である

ソフトウェアにおける設計=基本設計・要件定義~デバッグ
プログラミングは設計。
エンジニアが作ったコードは、ハードウェアの設計図に該当する。
(今の日本じゃ、プログラマ軽視だから、こういった考えは出ない気がする。)

改善の対称となるのは、コード。
改善を加えるのは、設計ではなくコードで、コードを直す必要がある。
そのためには、優秀な設計者(プログラマ)が必要。
プログラミングとは、仕様のコード化ではない。仕様を改善する作業を含んでいる。
(前者の考えは、ただのワーカー。プログラマ軽視はここから来ている気がしてならない。)

コードは必ず変更される

コードは修正されるもの。
一度書いて終わりということは、ほぼない。 なので、変更されることを想定してプログラミングする必要がある。

コード = 書いているより、読むことのほうが長く時間を使う。
書くのに時間をかけても、読みやすいモノを作るほうがいい。
長い期間で見ると十分に元が取れる。

原則

プログラミングのガイドライン

シンプルにしておけ、このバカ野郎!!

コーディングで大事なもの = シンプルさ
追求しないと、無秩序→複雑→カオスのコンボが炸裂する!
複雑なコードは、修正しにくくバグを量産し、コードを腐らせる。(「コイツ、腐ってやがる!」ってクロトワ以外からも言われる)
常にシンプルな状態を保つ事を心がける。
シンプルに保つためには、以下の事に注意する。

  1. 新しく覚えた技術を使いたい!
  2. 将来の必要に備えたい
  3. 勝手に要件を加える

欲望を捨てて、プログラミングすることが重要。 「大きいことは、よいことだ」って言っているCMがあったらしいが、あれは大間違いだ、バカヤロー(たけし風)

DRY ~ 繰り返すな

コードのコピペ厳禁!
コードの改善が困難かする可能性大

コードの抽象化を行い、重複の削除をなくす。
抽象化は、長い目で見ると有利だが、デグレードのリスクを梱包することになるので注意

DRYのプログラミングスタイル

やり方だけに注目せず、目的を意識すること!

やむをえないDRY違反

抽象化スタイルの違いから来るもの。
抽象化が違うものを一緒にする → 変更箇所の修正で思わぬ影響が出る

YAGNI ~ それは、きっと必要ない

コードは必要最低限

ソフトウェアの変化予測 = 不可能
必要なコードだけを書くようにする

コードの予測は外れる

汎用的なコード → 利用されないことが多い 無制限な汎用性の追求 → 不毛 使われない機能 → なぜ使われないかの存在理由不明で、消そうにも消せない

コードは今必要なものだけ

汎用性 < 利便性・単純性
使えること、シンプルであることが重要
過度の汎用性は、修正し難くなる

PIE ~ 意図を表現してプログラミングせよ

コード → 人が読むもの
コンパイラが読むものではない。

文芸的プログラミングを行い、コードをドキュメントのように書く。
(たまに、区分名で命名する奴がいるが、頭のイカれた理数系な気がしてならない?)

コメントは書く

コメントは、ないのが理想だが、現実問題として難しい。
コメントには、Why(なぜ)の部分を書くように心がける。
なるべく、コメントを書かなくてもよい実装を行い、足りない部分をコメントで書く。

文芸的プログラミングのメリット

  • ドキュメントを別途書かなくていい。コードに語らせる。
  • コードと説明が近くなるので、修正しやすくなる
  • コメントの質が上がる

SLAP ~ 抽象化レベルの統一

コードのレベルを合わせる

抽象レベルが揃う = コードの質が上がる。
閲覧性が格段に上がる。

コードに閲覧性と要約性をもたらす

抽象度によって処理をまとめる → 要約された処理ができる。
抽象度が合わない → 読み手に負荷がかかる。

OCP ~ オープンクローズドの原則

コードの変更を波及させない

拡張に対して開いている → 振る舞いを増やせる 修正に対して閉じている → 拡張した内容が他に影響しない

コードの柔軟化

OCPを実現することで、変化に強いソフトウェアが作れる。
ソフトウェアは、変更されやすいものなので。。。

ただし、過度な適用はやめるべき。
やり過ぎると複雑化する。
変化を予測して適用させる。

名前重要

以下の記事でも言及したので、興味ある人は見てみて!

suzaku-tec.hatenadiary.jp

コードで命名は最重要課題

  • 命名
    要素が正しく理解された。
    ふさわしくない名前 → 設計がおかしい。
  • 名前
    プログラマ同士が会話する上で必須。円滑な開発には、名前に配慮すべき。

コードを読む人への配慮

名前は、コードを読む人へのUI
適切な命名は、意図が明確に伝わる。

わかりやすい名前のメリット

  • 処理内容が把握しやすい
  • 名前に導かれて実装できる
  • 実装が説明的になる(文芸的プログラミング)

わかりにくい名前のデメリット

  • 処理内容を知るために、細部に目を配る必要がある。
    → 読むことを強いられているんだ!!
  • コーディング時、使用していい関数か判断に迷う
  • 実装が支離滅裂で分かりにくくなる。

コーディングは名前から

常に使う側、読む側の視点に立つ。 命名で注意すべきこと

  • 名前に情報を詰める
  • 誤解されない名前にする
  • 名前に効果と目的を持たせる
  • 発音できるものにする
  • 検索可能なものにする(英字1字とかは辞める)

(キラキラネームは、意味を込めてないから、辞めるべきだと思うんですよね~)

メンタルマッピング回避

メンタルマッピング = 記憶とイメージの変換
多くなると読み手の負荷が大きくなる。
一般的なモノを使い、特殊な用途の言葉をなるべく避ける。

ループバックチェック

名前を付けたら、名前を元に説明が行えるか確認する。
名前を元に説明できる = 正しく命名できている。

思想

プログラミングセオリー

変更に強くシンプルなコードを書くことに価値観を置く。
価値観は原則を通じてコードに適用する。
やることの価値がわからないと無意味

コミュニケーション

コード = コミュニケーションの場
コードとは、ドキュメントである。
コードにおいて、読んだ人が内容を理解し修正することができる = コミュニケーション良好
常にコードを読む側の視点に立つことが重要。

シンプル

コードの複雑は排除する。
目的達成のための複雑性は、仕方ないので許容する。

コードの複雑性

今後の開発の禍根になる
余分な複雑さ → 価値はない

コードの玉石を仕分ける

コードをシンプルに保つ = 玉石を選別する
シンプル過ぎると情報が少なすぎて分かりにくくなる。

柔軟性

コードの変更が容易であること コードは必ず変更される。
コードの拡張性を上げておく必要がある。
柔軟性のための複雑さは、許容してはならない。
柔軟性 < シンプル
トップダウンでの柔軟性 → 見当違いが多い
ボトムアップでの柔軟性 → 細部からのフィードバックであるため、的確

マイクロサービスの由縁はここからかな?
計画ばかり先行するとダメになるのは、柔軟性の重視から発展したマイクロサービスにも同様の習性がある。
トップダウンではなく、TDD駆動・DDD駆動で開発して、ボトムアップで問題上げて解決すると、マイクロサービスになる気がしました。

結果の局所化

変更の影響を抑えること。
そうすることで修正と確認を容易化できる。
結果が局所化されていない → 変更がいろんなところに発生する
結果が局所化されている → 影響範囲が狭く、修正が楽

実行するには、関係が濃密なコードをまとめておくといい。
お互いの呼出し回数が多い = 本来まとまっているべき処理が分散されている可能性がある。

繰り返しの最小化

重複は削除する。
そうすることで、修正の影響を局所化できる。
繰り返しは、結果の局所化を侵害する。
コピペによる同一コード生成 = ロジック変更があった場合に他の箇所は必要か判断しなければならない。
つまり、「一括置換でOK!」とは言えない。
コードを分割して管理することで、重複を排除しやすくなる。

対称性

コードに一貫性を持たせる。
そうすることで、類推できるようになり、抽象度の均等化、重複の排除が行い易くなる。
同じことをする場合、なるべく同じ表現を使うようにするのがミソ

宣言型の表現

宣言型プログラミングをして、コードの意図を伝える。
命令形 → 問題の解法
宣言型 → 問題の定義 = 問題の性質・制約が伝わる

フローがないので、読みやすくなる。

変更頻度

変更理由でグルーピングする。
そうすることで、変更範囲が狭まり、修正しやすくなる。
変更箇所が複数ある → 関連の強いコードが分散している
変更箇所が少ない → 関連性の高いコードが集約している。堅牢なコード。

アーキテクチャ根底技法

良いコードには「型(流派)」がある。(俺は、流派:東方不敗!!)

抽象化

概念的線引をすること。
捨象と一般化の観点をもとにまとめる。 捨象 → 性質から本質的要素を選別すること。本質を見つけやすくなる。
一般化 → 具体的対象から共通の性質を抜き出す。共通項のグルーピングをする。

カプセル化

データとロジックのグルーピング

情報隠蔽

必要ないものは見せない。
使用者が不正な操作をしないように、公開範囲は最小にする。
そうすることで、関連がシンプル化する。

カプセル化情報隠蔽の違い

カプセル化 → 関連する要素を集めてモジュール化すること
情報隠蔽 → 内部へのアクセスを遮断する

パッケージ化

モジュールのグルーピング。
意味のある単位にまとめる。または、分割すること。
そうすることで、モジュール郡の複雑度を下げる。

関心の分離

関心事毎に、機能や目的を分離する。 → 独立したモジュールになる。
また、関心事毎に変更はやってくるので、影響範囲が狭く、修正が行い易くなる。

インタフェースと実装の分離

  • インタフェース
    モジュールの機能を定義して、モジュールの使用方法を決めるのが役割
  • 実装
    モジュールの機能を実現する。ロジックとデータを持つ。

参照の一点性

定義は一度だけ行う。 = 初期化は一回だけ。
そうすることで、副作用のないプログラミング(不動のプログラミング)ができる!
副作用を抑えることで、状況依存の生涯が減り、コードの見通しが良くなる。

分割統治

大きな問題を小さく割る。
そうすることで、大きなままでは制御不能な問題を取り扱い易くする。

つまり、小さくして各個撃破!
兵法三十六計:混戦計:仮道伐虢

アーキテクチャの機能要件

「機能以外の機能」の観点
ソフトウェアの付加価値について高めることがアーキテクチャの仕事
なぜなら、非機能要件はリリース後の影響が大きいから。

セキュリティ非機能要件

書いてあることは、それほどでもない。
過去にまとめた情報セキュリティ試験の最初の方のことが書いてあった程度。

suzaku-tec.hatenadiary.jp

変更容易性

コードの変更を容易にする能力。
ソフトウェアは、どれだけ容易に改善できるかが超重要。
なぜなら、ソフトウェアの寿命は長く、最初のリリースで終わることはほぼない。
そのため、絶え間なく変化にさらされるので、変化に強くしなければいけない。

相互運用性

他のソフトウェアと会話する能力。
なぜ必要となるかというと、ソフトウェアは連携してシステムを構成することが多いから。
連携がしやすい = 資産を活かせる

効率性

リソースを上手く使う能力。
なぜ必要かというと、リソースは限られており、いかに上手く使うかがソフトウェアの価値であるため。

信頼性

機能を維持する能力。
信頼性を上げるやり方はいくつかある。

テスト容易性

効率的にテストする能力。
早く、安くテストできる = 質が高いテスト(牛丼と似ている!!)
テストの品質 = 本体の品質
テストをしやすくすることで、ソフトウェアの品質を高めることができる。

再利用性

再利用する/される能力
重視される理由は、できるだけ「作らない」ことで開発効率を上げたいから。
ただし、再利用可能なモジュールは、一般的なモジュール開発の3倍難しい。 → 一般的な問題も想定する必要があるので、複雑度が増しやすい。

7つの設計原理

  1. 単純原理
  2. 同型原理
  3. 対称原理
  4. 階層原理
  5. 透明原理
  6. 明証原理
  7. 安全原理
  8. 線形原理

レビューする場合、上記内容に気をつける。

単純原理

シンプルにこだわる。
なぜなら、複雑なところにバグはでるから。
なるべく、自然なコードにこだわる。

同型原理

形にこだわる。同じものは同じ表現を使う。
そうしないと、異物は目立たないため、レビューでバグが見つけづらくなる。
一貫性あるコードを書く。

対象原理

形の対称性にこだわる。 そうすることで、読むときに予測を立てることができる。

階層原理

階層にこだわる。
なぜなら、階層構造は読めやすいから。

線形原理

処理の流れは、線形にこだわる。
一直線の原理は読み易く、バグを解消しやすい。
なるべく分岐の少ないコードを書くように心がける。

明証原理

ロジックの証明にこだわる。
見ただけで正しさが分かるようにする。
そうすることで、不確実性を取り除き、明瞭なコードを書く。

安全原理

安全性にこだわる。
つまり、曖昧な箇所は、ありえない条件を考慮して、安全に働くようにする。
そうすることで、大事故への発展を防ぐ。

UNIX思想

UNIXの停留にある暗黙知を利用する。
なぜなら、UNIX設計は実践から得た「技」の集合体であり、覚えることで設計の正しさを覚えられる。

モジュール化の原理

控えめなモジュールを作る。
ソフトウェアは、複雑であるため、なるべくシンプルに作ることを心がける。
そうすることで、モジュールの関係が簡素になる。

  • シンプルなモジュール:他モジュールへの依存が少ない
  • 複雑さを減らす = プログラミングの真髄

メリットが多いので、モジュールの入り口を狭める事を心がけるようにする

明確性の原理

巧妙な作りはやめて、コードを明確にする。
そうすることで、障害が発生し難くなり、改修しやすくなる。

組み立て部品の原理

フィルタとして作り、ソフトウェア同士を組み合わせることができるようにする。
そうすることで、相互接続で相乗効果で価値の創出ができるようになる。

分離の原則

メカニズムからポリシーを話す。

  • ポリシー:ソフトウェアの前提に依存する部分
  • メカニズム:前提に依存しない独立した部分

メカニズムは安定しており、ポリシーは不安定している。
ポリシーの変更はやりにくく、ポリシーの変更はメカニズムの変更になるため。
ポリシーを分離して改善を行い易くする。

単純性の原理

コードはシンプルにする。
なぜなら、コードは自然発生的に複雑になるため。
シンプルさをチームの価値観の絶対文化にするように心がける。

倹約の原則

大きなコードは書かない。
なぜなら、大きなコードは制御不能であるため。
コードの継ぎ足しは、避けるようにする。

透明性の原理

ソフトウェア動作は見える化する。
そうすることで、デバッグに貢献する。

  • 透明性:一見見て内容を理解する
  • 開示性:内部の状態を監視・表現できるようにする。(カイジ性ではない。ギャンブル性は排除する)

安全性の原則

ソフトウェアを安定させる。
予想外の条件下でも、適切に動作させることで、堅牢にさせる。
考慮し過ぎると複雑になるので、なるべくシンプルにする。
ソフトウェアは堅牢な作りを心がける。

表現性の原理

情報はデータに寄せて表現する。
なぜなら、データはロジックより制御しやすいから。

驚きの最小原則

予想通りのインタフェースを作る。
そうすることで、学習コストが低くなる。
ユーザの既知を利用することが、学習コストを下げる。

沈黙の原則

ソフトウェアは寡黙にする。
エラーでいちいち指摘してくるソフトウェア = 使いにくい。
寡黙に作ることで、大事なことが伝わりやすくなる。
出力が多いと、情報過多で見逃しやすくなる。
ユーザの注意力・集中力は大事なリソースなので、情報の出力は多用すべきではない。 なので、重要な情報のみ出力する。

修復の原則

修復失敗時は、処理を停止する。
なぜなら、エラー時の継続続行は被害が拡大するから。
後手に回ると、被害は雪だるま式に大きくなる。
エラー通知は、「けたたましく」

経済性の原則

プログラマの時間は大切にする。
プログラマの時間の浪費が、目先の経費より高く付くことが多い。

時間浪費の原因

  • ハードウェアが貧弱
  • ソフトウェアに対する制限
  • 環境へのルール・制限

生成の原則

「コードを書く」コードを書く。
手作業はなるべく避けて、無理に全てを対象としない。
そうすることで、安価で高品質なコードを生成することがでできる。

最適化の原則

早いコードより正しいコードを作る。
なぜなら、早い段階での「速いコード」は、設計を破綻させる。
最適化にこだわると、いくつか問題点が出てくる。

  • 透明性や単純性の損失
  • 部分的最適化≠全体の最適化

正しくしてから早くすることを心がける。

多様性の原理

選択の多様性を受容することで、よりよいやり方を模索する。
多様性を失くす → 思考停止に繋がり、危険!
人一人のの想像力には限界があるので、多様性は積極的に受け入れる。

拡張性の原理

拡張できるように設計しておく。
なぜなら、ソフトウェアは成長しなければいけないから。

小は美なり

小さいソフトウェアは美しい。
なぜなら、小さいソフトウェアは扱いやすから。

  • 理解が簡単
  • 保守が容易
  • マシンリソースが節約できる

1つ1仕事

1つのソフトウェアは、1つの仕事をする。
そうすることで、ソフトウェアが純粋になり、再利用しやすくなる。

即効プロトタイプ

できるだけ早くプロトタイプを入手する。
なぜなら、試行錯誤なしではよいものは作れないため。

効率性より移植性

効率性よりも移植性を重視することで、ソフトウェアの価値を持続させる。
ハードウェアによったソフトウェアは、移植性が低く、ハードウェアの優位性に依存する。
移植性を高く作ることで、ハードの優劣が致命傷にならないようになり、価値を持続させやすい。

データはテキスト

バイナリファイルよりテキストファイルを優先する。
なぜなら、テキストファイルは万能で、移植性が高く、人が見やすい。
ツールやコマンドで処理することも容易である。

レバレッジ・ソフトウェア

ソフトウェアの梃子で力を増幅させる。

  • 力点:ソフトウェア
  • 支点:ユーザ
  • 作用点:操作結果

ソフトウェアを複数・ユーザの近くで動作させることで、結果が多くなる。
少ない労力で巨大な成果を得ることが重要。 → 手作業を自動化させる。

シェルスクリプト活用

シェルスクリプトで接着する。
そうすることで、梃子の効果が増幅する。
普段使っている言語を使ってのスクリプト → 移植性が悪い
特別な理由がなければ、コマンドラインで事足りる。

対話インタフェース回避

拘束的ユーザインタフェースは避ける。(SMプレイはらめぇぇぇ!!)

対話型の問題点

  • ソフトウェア固有の使い方を覚える必要がある
  • 連携がしにくい
  • 待ち時間の増加
  • 字句解析による入力チェックによるコード量の肥大化
  • ソフトウェアの機能過多

フィルタ化

ソフトウェアは、フィルタとして設計する。
なぜなら、ソフトウェアは入出力であるため。

UNIX哲学

ただの格言集

環境カスタマイズ

使いやすいようにアレンジする。

小文字使用

識別しやすく読みやすい。

森林保護

紙は編集できないので使いにくい。
(日本の企業って紙で資料欲しがるけど、なぜなのだろう?
エコエコうるせぇのに、こういったところで矛盾を感じる。)

沈黙は金

表示は極力控える。
無意味なデータは見せないほうが見やすいから。

日本はあまりできてないことが多い。
繁華街を見て育ったせいか、ごちゃごちゃしているところに風情を感じる特徴がある気がする。
ただ、それは現実世界であって、ディスプレイで見るとすごく汚い。 付け加えると、会議では発言するほうがいいが、余計なことは言わない方がいい。
あとで背中からナイフで刺される。

並列思考

小さく分割して同時に実行できるようにする。

部品コラボレーション

小さい部品の集合 > 単体ソフトウェア

90%解

100%上手くやることは困難。
費用対効果を考えて仕事しようね!

劣るが優る

高品質で高価 < 効率的

階層指向

階層構造は、優れたアプローチ。
単純であるがゆえに強力である。

視点

凝縮度

モジュールは「純粋」に作る。
なぜなら、雑じりっけのあるモジュールは、脆い&硬いため、変化に対応出来ない。
鉄と一緒。純度の低いものは硬いが、かけやすい。 硬さより柔軟性が、ソフトウェアでは大事。

結合度

モジュール間は「疎遠」にする。
結合が密だと、互いに影響を与えて再利用しにくくなる。

直交性

コードは独立させる。
なぜなら、直行コードは堅牢になるから。
堅牢に作ることで、変化が局所化され生産性が上がり、リスクが軽減できて問題部分の隔離ができるから。

可逆性

戻す・やり直しができることが可能な選択をする。
なぜなら、ソフトウェアに最終決定の権利はないため。
最終決定を下すのは利用者。ソフトウェアは、物事に対応できるようにしておくのが仕事。
ただし、やり過ぎには注意

コードの臭い

コードの凶兆・問題点は見逃さない。
リファクタリングを継続的にすることは、ソフトウェアでは必須。
臭い臭いの傾向を知っておくと良い。

  • よく見る
  • 長過ぎる
  • 大きすぎる
  • 多すぎる
  • 名前が不当

技術的負債

問題コードは「借金」である。
すぐに返済できるなら問題ないが、返済が長引くと利子が付いて返済不可になり、自己破産する。
なるべく、早めに返済を行い、問題コードと上手く付き合う方法を知る。
技術的負債 → 悪循環を生む。
「手抜き」が必要になることもある。
その場合は、借金をコントロールする必要がある。

借金は悪だと考える思考が強すぎるが、逆に考えるんだ。
借金しちゃってもコントロールしていれば問題ないさと。
できればないほうがいいけど、意図せずにしてしまうこともあるので気をつける。

問題コード発生の誘因

  • 経験不足
  • 〆切のプレッシャー
  • 読みにくいコードの存在
  • 特殊化
  • 複雑性
  • 悪い設計

チーム文化による問題コードの誘因

習慣

プログラマの3大美徳

プログラマは「怠慢」「短気」「傲慢」であれ!
ただし、TPOは考える必要があるけどね。

理由

  • 怠慢:労力を減らす手間を惜しまない
  • 短気:効率的に作業してないことに怒りを感じること
  • 傲慢:過剰な自尊心を持つことで、己を強く保つ努力をする

もっと傲慢な日本人は増えて欲しいところ。
※ほんとうに傲慢ならムカつくが。。。
場の空気を読める傲慢な奴は、職人であることが多い気がする。
なんとなしに作業している奴は、なるべく消えて欲しい。

ボーイスカウトの原則

コードは掃除して帰る。
つまり、改善する努力を続けること。そして改善は人任せにしないこと。
そうすることで、コードの腐敗は防止される。
コードは生物で、時間の経過とともに腐敗して品質が下がる。
前よりも少し綺麗な状態にすることで、品質が保たれるようになる。

コードは改良してからコミット

完璧を目指さなくてもいい。
少しの改善をすることが重要。

プログラミングは急がば回れ

最短で時間とコストを稼ぐ = 腐敗したコードができる
回り道のほうが、品質が上がる。(相対性理論??)

パフォーマンスの箴言

「速い」より「よい」コードを作る。
早過ぎる最適化 = 諸悪の根源(つまり、ドレッド・ルートである!)
速いコードは、「割に合わない」ことが多く、大切な何かを失う。
※速さは何かとのトレードオフで成り立つ

最適化で失うもの

  • 可読性
  • 品質
  • 複雑性
  • 保守の阻害

なるべく正しさを追求した後に最適化を行い、失うものを最小化する。

エゴレス・プログラミング

エゴを捨ててプログラミングしなさい。
自尊心を捨てて「よりよいものを作る」に価値観を置く。
つまり、コードの私物化をやめて、アドバイスを謙虚に受ける姿勢を保つ。

エゴっぽい事をいう人がいたら、「エゴだよ、それは!(アムロ風)」に言ってみると面白いかも。。。

エゴレス・プログラミングの十戎

  1. 自分自身が間違いを犯すことを理解して受け入れる
  2. 書いたコードは専有しない
  3. 上には上がいる
  4. 相談なしにリファクタリングしない
  5. スキルが劣る人にも、尊敬・敬意・忍耐をもって接する
  6. 絶対変わらないものはない事を意識する
  7. 信じるもののために戦い、負けは受け入れる(これを出来ない奴が戦争を続けるのだ!(ガンダム風))
  8. ひきこもらない
  9. 人の批判より、コードの批判

1歩ずつ少しずつ

ステップ・バイ・ステップで物事を進め、複数の事象を相手にしないようにする。
なぜなら、手堅い歩みは効率敵だから。(イソップ童話のウサギとカメ??)

小さいけど確実な一歩 = 結果的に品質が上がり、効率的になる。
複数のことを一度にすると、作業が混線して失敗しやすくなる。

TMTOWTDI ~ やり方は、ひとつではない

ツールの多様性は、善。
達成する手段が多い = 使う側がシンプルに使える。
使われる方がやり方を複数用意することで、使う側がシンプルに使えるように選択することができる。

手法

曳光弾*1

常に現状を理解して、即時フィードバックできる仕組みを持つ。
そうすることで、暗闇の中でも道筋を照らせる。
つまり、ソフトウェアの意思決定を迅速にできる。
目標と現在の差分を知る手段をもつことが重要。

曳光弾のメリット

  • フィードバックが得られる
  • プログラマが活躍できる舞台が、早めにできる
  • デバックやテストが正確にできる
  • デモ可能なソフトウェアの確保
  • 進捗の明確化

最初に動作する土台を作る

プロトタイプの作成を優先する。

プロトタイプと曳光弾の違い

  • プロトタイプ
    理解を検証する手法
  • 曳光弾
    連携方法の正しさを証明する手法

アプローチは似ているが、目的が違う。

契約による設計

呼出し側と呼び出される側の取り決めを行う。

  • 呼出し側
    事前条件を満たすようにする。
  • 呼び出される側
    事後条件を満たすようにする。

取り決めを決めることで、思い違いを早期に発見する。

防御的プログラミング

「かもしれない」プログラミングを心がけ、不足の事態に備える。
自分の身は、自分で守る事を忘れない。
そうすることで、開発と運用が安全運転できるようになる。

バリケード戦略

バリケードを作り、問題の拡散と侵入を防ぐ。
インタフェースを安全地帯への境界にするとよい。 バリケードの内外で、エラー処理内容を分ける。

ドッグフーディング

ソフトウェアの味見をする。(命名は犬に味見をさせて、死なないか見るため??動物保護団体から苦情きそうな名前。。。)
開発途中のソフトウェアは、洗練されておらず、マズイ可能性大。
率先して味見して、塩梅を確認することが重要になる。

ラダーダッキング

「説明する」というデバック手法のこと。
説明する行いが、問題解決方法に気づける可能性が高い。
比較的安価でデバックできる。

自己解決を促す

説明する = 問題の暗黙的過程を明確にする行い。
間違いに気づき、解決の糸口を見つけられる。

無機物に説明

人に話す前に、人形に対して説明してみる。(ちょっとメンヘラみたい。。。)
そこそこ効果があることが証明されているらしい。
ベストは、現場にいる同僚のエンジニア。
(自分、居ても話しかけられないのですが。。。)

コンテキスト

文脈会話、文脈思考をする。
そうすることで、会話や思考の迷子になることを防ぐ。
文脈ベースの説明は、状況や背景がわかり、利用価値が高い。
そして、思考するツールとして利用できるので、問題解決の作業が良くなる。

コンテキストの伝導力

最初にヒントが有る状態でコードを読むことができるので、可読性が飛躍的に上昇する。
脳は、最初のヒントで処理能力が向上するため、その恩恵が得られる。

チームはハイコンテキスト思考*2

空気が読める・阿吽の呼吸ができることは、チームとしての最大の強み。

日本人は、それに比重をおくので、チームとして良い状態になることがある。
ただし、重視しすぎたり、リーダーが無能だと足の引っ張り合いが加速する気がする。。。

ハイコンテキストチームの特徴
  • オーバーヘッドが短い
  • 意思疎通が楽で、コストが少ない
  • 新規加入しづらい
    コンテキストが共有されてないので、摩擦が生じやすい。
    ローコンテキストで対応する必要がある。

(日本で村八分という考えがあるのは、ハイコンテキストだからではなかろうか。。。?)

コード共通化はコンテキスト指向で

コード共通化は良いことだが、依存性を内包することになるので、コンテキストを意識して作る。
コンテキストを意識することで、役割を明確化しておく。

プログラマコンテキストスイッチ*3

プログラマの理想 → フロー状態(ゾーン)に入ること これは、スポーツ選手だろうが変わらない。

フロー状態は、入りにくく維持しづらい。
割り込みが入ると、簡単に切れる。

マネージャには理解されないもの。
なぜなら、割り込み対応がマネージャーの仕事だから。

プログラマの理想を実現するためには、職場の意識改革や文化改革が必須。
プログラマの時間の重要性を理解することが重要

法則

ブルックスの法則

要因追加は「火に油」。
遅れを取り戻すための要因追加は、遅延の拡大になることが多い。
なぜなら、「人」と「月」は交換不能だから。
たとえば、6人月の作業を6人1ヶ月でやるのと、2人3ヶ月でやるのでは、仕事の効率が違う。

依存関係によるオーバーヘッドが発生するため、単純な後からの増員は、遅れに繋がる。 無条件の増員は避ける。
やる場合は、ユーザと調整して、機能に優先度を付け、リリースを行う。

アジャイルが出来た由縁はここにある気がする。
人月神話については、過去に読んだことがあって、人月に対する考え方が変わった。
一旦どこかでまとめたい。

コンウェイの法則

アーキテクチャは組織に従う。
なぜなら、アーキテクチャは、情報伝達構造に従うため。
組織構造 → 情報伝達構造 → アーキテクチャ

格式ばった組織は、やたらと設定ファイル好むのは、このせいなのかな???

アーキテクチャ設計後に組織編成せよ

組織の都合でできたアーキテクチャ = 最適ではない
完成品に悪影響が出ることがある。
早期に作成されたアーキテクチャも、近似解であって正解ではないので、早期の組織編成は止める。
十分に検証した後に組織編成を行う。

それまでの間の組織編成は、変化に強い組織編成を行うことがいい気がする。(個人の感想)

組織とプロセス

相互依存の関係にある。
境界となる箇所を探して、単独の良し悪しで決めることは控える。

以前読んだ、組織パターンに書いてあることが多く引用されていた印象がある。
過去に読んだ内容をまとめた記事があるので、そちらも見ることをススメる。

suzaku-tec.hatenadiary.jp

割れた窓の法則

悪いコードは「蟻の一穴」(ユートォォ!!)

以下、ユートのセリフ引用。

巨大な建物も蟻の一穴から崩れるという。 君には融合という壁に我々が最初にうがつ小さな亀裂になってもらう

つまり、ちょっとした綻びが、全体を崩壊されるものになる。
それは、ソフトウェアも同じである。

悪いコードは邪心を引出す

悪いコードがある → 適当に作業する心理にさせる

人の反応は、長く弱いストレスに敏感に反応する。
短期の強いストレス < 長期の弱いストレス

悪いコードの存在が、さらなる悪いコードの呼び水になり、負の連鎖を誘発する。
(悪いコードは儀式魔法で、負の連鎖は儀式モンスター!!)
結束の硬い組織が、少しの疑念で総崩れすることはよくあること。
歴史がそれを語っている。

コードは清潔に保つ

悪いコード = 発見次第、修正する 良いコード = 悪いコードが入らないように細心の注意を行う。
そうすることで、邪心の入るスキを失くす。

人は人を真似る

行動を真似る = 人の特性
悪いコードの存在は、人の特性を利用して連鎖を起こす。

エントロピーの法則

エントロピーとは、物理学用語で、無秩序の度合いのこと。(まどマギ用語ではないのか!?)
ソフトウェア開発は、エントロピー増大の法則に強く縛られている。
何がいいたいのかと言うと、コードは自然と腐っていくものである。
何もしないと、限界を超えるまで無秩序は増大する。
コード腐敗の兆候を掴み、アジャイル的な対応で腐敗を許さないようにする。
アジャイル的な対応を撮るのには理由がある。
なぜなら、腐敗は流動的なものであるため、目的を固定化して改善しても、対応が終わる頃には状況が変わっていることがある。
イテレーションを回して、継続的に改善することが必要。

80-10-10の法則

プログラミングに万能薬はない。

ユーザの要求
80%は実現可能。残りの20%が問題。
10%は、相当な努力が必要。のこりの10%は、完全に実現が無理。
そのため、プログラミングの問題領域を決めておく必要がある。

ジョシュアツリーの法則

名前がないものは、見ることすら出来ない。
まどか神が見えないのは、全員名前を忘れたから。

名前を付けることで存在を知る

物や概念 → 名前があることが前提
名前があることで認知され、再利用される。
この仕組を利用したのが、デザインパターン
設計ノウハウに名前を付けることで、再利用できるようにしている。

「コミュニケーション」って言葉も、元来日本には存在しないハズだが、海外の考え方に触発されて普及した感じがする。
普及したはいいが、そもそも日本の風土にないため、個々で定義が変わっていて、意思疎通の邪魔ばっかりする。
言う方は楽でいいかもしれないが、聴いてるほうは翻訳のストレスに悩まされる。そして認識齟齬を生む。
それが問題化すると、コミュニケーションうんたらを言い始めるから始末におえない。まったく、いやな世の中になったものだ。
日本のリーダー層やトップの人間が、コミュニケーションって言い始めたら、だいだい怪しいと思うのが、最近の心情である。

セカンドシステム症候群

2回めのリリースは危険だ!
なぜなら、慣れからくる自身が、失敗を招きやすいから。
慎重な判断をすることを常に心がける。

車輪の再発明

既にあるものを作ること。
時間の無駄であることが多く、既にあるものが品質が優れていることが多い。

f:id:suzaku0914:20160627064818j:plain

ロードローラー使ったのも、車輪の再発明を揶揄してなのかぁー!!!

車輪の再発明をしてしまうことは、「車輪の知らない」「車輪を作りたい」という背景が存在している。

車輪以外に注力する

本来やるべき作業に注力する。
その状態を作るために、チームミーティングを行い、情報収集を行う。
また、エゴの少ないプログラミングを徹底する。
作りたいから作る → プログラマのエゴ
日々、使えそうなものは調査・把握する努力を怠らない。

車輪の再発明をすべき時

  • ビジネス目的
    再利用する = 差別化を止める
    ビジネスコアな部分は再発明をやめて差別化を図ることが重要。
    そのためにも、ビジネス目的は明確にしておく必要がある。

  • 学習目的
    存在するコードを使うのと、ゼロからソフトウェアを作るのとでは、得られる経験値が違う。
    車輪の再発明は、学び技術力を高める上で必須になる。

ヤクの毛刈り

本当の問題に辿りつくことは難しい。
なぜなら、トラブルは芋づる式。
問題を解決しようとしたら、別の問題が出てきて、最終的に何を解決したかったのか忘れることがある。

そのような状況に陥った場合、早々に切り上げる方がいい。
問題が起こったら、何が目的だったのか考えるクセを付ける。
目的と違う・コストと見合わないと感じたら、作業をやめて別の道を模索する。
そうなった経緯は、参考になることが多いので、メモしてメンバーに共有すると、組織が強くなる。

トラブルが、「ToLOVEる」って誤変換ばかりされて、困った。
あんまり打たないハズなのだが、Google日本語入力は、俺をそうゆう人間だと判断したらしい。
もしくは、そういうことをGoogle検索する奴が多いってことだな。

感想

結構いろんな本の言いたいことを、体系的にまとめていた気がする。
内容が濃ゆいので、読んで自分の腹に落とし込むのに結構時間がかかった。
基本的には、自分の考えと間逆なことは書いてなかった。
初心者に理解させるには、難しい内容な気がする。
自分は、過去の経験から記述内容を腹に落とせるけど、初級者はそれがないので辛いのでは?と思いました。
とはいえ、幅広く知識を得るには優れた本なので、1冊持っているのがいい気がします。
気になったことは、より専門的な本を買って読めばいいので。
ヒントになることは、いくつかあったが、より深く探るには適さない。
幅広い知識体系と考えを持ちたい人にオススメの本でした。

全体的に読んでみて、シンプルって言葉がよく出てきた。
やはり、ものごとの本質は、シンプル性を好むのだと強く確信できた。

次は、SOFT SKILLSの日本語訳でも読もうかな?

*1:発行する弾丸のこと、飛んだ奇跡がわかり、即時フィードバックができる

*2:背景・価値観に共通認識が多い状態

*3:状態の切替