プリンシプルオブプログラミング1回目

# 前振り
先日以下のイベントに参加してきました。

https://academist-reading.connpass.com/event/331143/

約１時間でプリンシプルオブプログラミングという書籍のワークを行うというイベントです。

https://www.shuwasystem.co.jp/book/9784798046143.html

こちらの書籍は、結構前に完読していたものの、そこまで深ぼった議論はしていなかったので、復習がてら再度参加してみようと思ったのがきっかけです。

ちなみに書籍の中にある設計原則や、設計思想などはいたって初歩的なものから、
防御プログラミングと契約による設計の考え方の違いなど、設計基本的な概念まで
幅広く網羅されています。

:::note warn
ただし、この書籍にはコンポーネント原則6つは記載がないので、
マイクロサービスやモジュラモノリスなどマクロなアーキテクチャを考える際は、
別途　クリーンアーキテクチャなどの書籍のコンポーネント原則6つを
基礎として抑えなくてはならないと感じた。
:::

では、次項からは１回目の振り返り内容を記載する。

# 1.1 プログラミングに銀の弾丸はない
プログラミングに限ったことではなく、あらゆるものに対して絶対的な正解はない。
これはプログラミングだけではなく、企画や要件定義などのビジネスサイドでもいえる話と感じている。
要求から要件に整理しやすくするための思考フレームワークなどは確立されているものの、
それを使ったからじゃあ要件定義が絶対うまくいくって保証はない。

## 同調性
ソフトウェアが実世界と対応していなくてはならないというもの。
実世界の様々な他のソフトウェアやハードなどと関係しあいながら存在していること。

### コンウェイの法則との関係性
これはビジネスサイドとシステム開発サイドとの間に分断があったりすることなどによって
乖離が発生したりするなど、ある意味コンウェイ法則も関連しているように感じる。

## 不可視性
別の方が「新人のころ、無理やりプログラムを構造化して理解しようとしたり、
割と他人が気軽に見てもらえると思っていた。
すごい人なら、ぱっとコードを見ただけで全部わかると思っていたが、
それは難しいことを学びました。」とコメントしてくれました。

### ADRとの関連性
これはコードだけではなく、全体の構造などにおいても言えることです。
特にアーキテクチャがなぜ今の形をとろうと思ったのか？などは、
全体の構造をモデリングして見ただけではわからない。
ゆえに、ADRなどのWhyになるものがなくては、目に視えないものを感じ取ることは不可能。

### 保守性といった目に視えない品質
また、上記の方のコメントに対して私が感じたものとしては、
保守性　なかでも変更容易性という目に視えない特性をどう定性的に感じ取るのか？
という話を議論の中でしました。
「他人がそのクラスを見て認知負荷がかかるようなもの。
何をやっているのかをパって言えないものは、もしかしたら単一責務ではない可能性
ということが超定性的にチェックできる」ということです。

# 1.2 コードは設計書である
上流の基本設計→詳細設計→プログラミング→テスト→デバッグ
一連の流れすべてで設計であって、アウトプットはコード。
ゆえに成果物のコードこそが設計書。

これは非常にわかります。
あくまでもUMLを使ったモデルなどは、机上の空論でしかない部分もあり、
実際にコードにして動かしてみないとわからない点も多々ある。
ドメインモデリングをする際に、ビジネスからコードまでを一貫性を持たせる
というのもこれの考え方がベースにあるからでしょう。

## ロゼッタストーン
ロゼッタストーンとは、将来の保守担当者に対する簡潔な手引書のこと。
ソフトウェア開発環境を理解するのに必要な情報と、
アーキテクチャを理解するために必要な情報を記載する。

議論の中で、他の参加者の方々も以下のようなコメントをされていた。

:::note warn
ロゼッタストーン自体うまくいったことがない
:::

:::note warn
コードにはWhyがないので、コメントかプルリクに情報を記載するようにしている
:::

:::note warn
情報があちこちに散らばるといけないので、
設計仕様書+コードにコメントで書くことによって対応している
:::

### 自分の見解
この中でも情報があちこち散らばるというものは、実際の案件の中でも経験があり、
大前提のビジネス要件が変更されたのに、コードのどこを変更したらいいのか不明で
それを探すのにめちゃくちゃ時間がかかる。
さらには影響範囲の調査にも時間がかかるということを経験している。

かといってすべてのビジネス要求、誰のどんなことを満たしたいのか？
というものからすべて記載していると、
そのコードに記載されている情報があまりにも膨らんでしまう。

そこで思うのは、

:::note info
そのモジュールの粒度に合わせて、どこのWhy情報までを記載するのかを決めるということ。
:::

クラスという最小単位のコードに、ビジネス要求の情報を記載っていうのは、
あまりにも詳細なパーツに上位の目的の情報を書くことになる。

たとえばモジュラーモノリスアーキテクチャの場合で、
あるビジネス要求を満たしたい場合に、モジュールAとBが連携することで成立するとする。
その際には、このモジュールAとBのそれぞれの使用する機能に目的の情報を記載し、
もしもオブジェクト指向で設計しているのなら、その情報は事前事後条件の記載箇所に
わたしは書いてしまっていた。
そうすることで、上位目的がわかり、しかも事前条件、事後条件なども一緒にわかり、
マクロに見てどのように処理が連携し合うのかがわかりやすくなるからだ。

# 1.3 コードは必ず変更される
## コードは無常である
不確実性の高いプロジェクトでは、最初のリリースだけで要望を網羅したソフトウェアをつくることは不可能。
仮説検証サイクルを回しながら、徐々に真の要求を浮き彫りにしていき、
その過程で何度もコードを修正する必要性は避けられない。

## 変更に強いコードを書く
コードはメンテされるものであって、書く時間よりも読み解く時間の方がかかるもの。

:::note info
絶対に変更がある→変更に強いコード→読みやすいコード…読めなきゃ話にならない
:::

変更からの保護として代表的手法は、高凝集、疎結合を実現すること。

この変更に強く、読み解きやすいという状態にするためには、

:::note info
変更容易性を高め　かつ　解析容易性　も同時に高める必要性がある。
:::

## 注意点として
変動からの保護として、interfaceを用いる手法があるが、
変更が入るからと、どこにでもinterfaceを導入してしまっては逆に複雑怪奇になってしまい、解析容易性が下がる可能性が出てくる。
その塩梅は簡単でないものの、たとえば以下の原則の考え方を１つの指標として、
設計することが個人的には意図がわかりやすくてオススメ。

https://qiita.com/Kudo_panda/items/58364763f456e3212d89

コンポーネントの抽象度と安定度合いが極力同じようにするなどして、
変更の頻度などを含めた意図がわかりやすくなっているようにするとかの工夫が必要と感じる。

## 事前事後条件などの変更
interface設計の際の１つの大事な考えとして、
仕様変更に伴う、事前事後や不変条件の変更　というものがあるため、
本にはないが、ここを議題として挙げさせていただきました。

Web系のサービスを主にやられている方は、暗算的に事前事後の変更などを行い、
その上で都度修正しているそうです。

ただわたしは、暗算でそんなことをできないような案件にいたのもあって、
ラフでもいいからアクティビティ図などを書いて、
具体なフローの事前事後などを明らかにした上で、それらを抽象化し、
interfaceの事前事後条件などをボトムアップ式で明らかにしていく。
これがやっぱり現実的なinterfaceの設計のプロセスと感じています。

# つづく