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

# 前置き
今回は、3章の
【対称性】【宣言型の表現】【変更頻度】の３つがテーマです。

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

# 対称性
図形的に見て一貫性を持たせるということを表している。
これは例えば、BAビジネスアーキテクチャとAAアプリケーションアーキテクチャの構造を相似形にするといったものも含まれている。(BAとAAの関係図は下図)


<img width=500 alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2781175/5ebad02c-6e63-f378-0747-1522ea292e54.png">


それ以外にも同じ種類のものは同じレベルで扱うなどという、関心の分離やSLAPなどとの関係性も強い。

## 理由
対称性があると理解がしやすい。これは保守をする上で欠かせないことだ。
対称性がある場合とない場合とで比較してみよう。
あるシステムの名前をXとしよう。
X内のアーキテクチャは、マイクロサービスの形をとっているとする。

### 対称性がない場合
仮にここで、X.aというコンポーネントは、マイクロサービスの粒度であるものの、
X.bというコンポーネントは、マイクロサービスよりも１段階詳細なコンポーネントであるという状況であった場合、こういったものを対称性がない状態と呼ぶ。
そしてこれは同時に、SLAP違反である状態。
このような状態では、可読性が非常に悪く、保守もしにくい。

### 対称性がある場合
X.aというコンポーネントは、マイクロサービスの粒度である場合、
他のX.～というものに関しても、マイクロサービス粒度である状態が対称性があるといえる。これなら、どう考えても見通しがいい。
すると、異なるコンポーネントに配置された似たコードが、
実は概念としても本当は同じであるか？という判断もしやすくなることにつながる

## 実現方法
### 対になるメソッドを作成
これは後述の章で出てくる充足性や完全性を満たしやすくするうえでも重要なものである。
addメソッドがあったら、当然deleteメソッドも必要だよねとか。

ただし、充足性のチェックするうえで
「addがあるなら、deleteもないとおかしくない？」という問いかけをしたとしても、
それがステークホルダーにとって関心の薄いものであれば、YAGNI違反を引き起こしかねないため、その時点ではまだ定義しないという判断が無難であろう。
特殊なドメインによっては、削除はせずに、一方的に追加するだけの処理を求められるものもあるからだ。

:::note warn
まだ不確定要素が大きくてYAGNI違反になりたくないから、意図して「まだ追加しなくていい」と判断するのと、意識せずに対になるメソッドをさぼるのとでは異なる。
:::

### データライフサイクルでグルーピング
これはあるグループ内(コンテキスト内)の特定のデータのみ異なるタイミングで精製や消滅ということをNGとするということ。

データのライフサイクルを共にするってことは、それだけデータの静的な結合状態が強いってことである。
たとえば、コンポジション(UMLでいう黒のひし形マーク)関係の所が、まさにそれである。
その蜜結合状態は、当然同じデータ境界内にまとめて置きたいと思うのが自然である。
このあたりは、ER図だけではっきりならない場合、DFDも描くことを推奨する。

### メソッド内で呼び出す処理に対するSLAP
ある親メソッド内でaを呼び出して、次にbを呼び出し、cを呼び出すというときに、
それらの抽象度を揃えるということ。
これらの抽象度が揃っていないと、可読性が悪くて、コードを見てすぐに頭の中で
アクティビティ図などに変換がしにくい。

・機能の構造モデルを描くこと
・動的な側面からのアクティビティ図を描くこと
・抽象度が不明な場合には、一回抽象度の高い状態の機能を分割統治していき、
再度前提の抽象的な機能にまで戻るという風にすると、他の機能と抽象度を合わせやすい。

### 同じ引数を受け取るようにする
パッケージ以上の粒度感のコンポーネントが外部に提供するAPIに送る引数の型を揃えた方が、ポリモーフィズムが使いやすいからである。
もしもコンポーネント内の中身のバリエーションごとに引数の型を変えるとなると、
クライアントコードから見て、コンポーネント内の詳細を知ってしまっていることになり、
情報隠ぺいが機能していないし、疎結合状態ではなくなってしまう。
これは中身のサブコンポーネントのどれかを変更した際にも、クライアントコードにまで影響が出てしまう。

つまり対称性を意識した設計をしていると、おのずと疎結合にもなりやすいということ。

## 議論で出た話
主に議論で出た話題は以下の図のようになっています。

<img width=500 alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2781175/725d9e5d-4d4d-c09c-1d98-ec16d06d6ef1.png">

### Railsのディレクトリ構造
Railsのディレクトリ構造は、フレームワークによって規定されている。
それによって自然といろんなものがどこに置かれるべきなのか？
といったものが整理されて、コンポーネントごとにばらばらではなく、
世界中で一貫性を持った構造を維持しやすくなるよね～という話が出ました。

フレームワークの規約によって、強制的に対称性を満たすというのは、
アーキテクチャがごちゃっとなりにくくするためにも重要です。

### ループバックチェックとの関係性
対になるメソッドを追加しないと、ループバックチェックをした際に、
オブジェクトの名前を類推できないほどの低い充足性であった場合には、
対になるメソッドを追加してあげなければならない。
このときに、その対になるメソッドとかがどのステークホルダの要求と結びつくのか？
というトレーサビリティマップを定義しておくことをお勧めする。

### SLAPやKISSとの関係性
一貫性を持ったコードにしたいなという気持ちが根底にあって、
そのうえでこんな風な分類を心がけると保守しやすい奇麗なコードになるという意味で、
テクニックとして、カプセル化とか、SLAP、KISSがあるというイメージ。

## 関連する原則
SALPやKISSと関連性が高い。

対象であるがゆえに、自ずとSLAPを満たしており、かつシンプルでわかりやすくなる。
また、対称性にすることで概念としては異なるが似た部分、
概念的に同じもの、全く異なるものとの境界が浮かび上がりやすくなり、
自然とDRY原則も満たしやすくなってくる。


# 宣言型の表現

## 理由

## 実現方法

宣言型のプログラミングは、変更頻度の高い所に適用した方がいいものという話をしました。
その際にわたしは頭の中で下図のような２軸マトリクスで評価しています。
もちろんこの配置関係は固定的ではなく、外部環境変化によって変わります。

変更頻度が低く、かつ周辺コンポーネントへの影響度合いも小さいような箇所に
宣言型を用いてもそこまで効力は発揮されないでしょう。

# 変更頻度

## 理由

## 実現方法

## 単一責務原則との関係性