「良いコード」を探し求めて
最初はリファクタリングを通しての、理論として学んだ設計原則の実践のお話し。
品質の認識合わせ
「ソフトウェア品質を向上させるために、保守性を上げよう」といっても、
保守性には、以下の5種類がある。
その認識合わせをしましょうというお話。
ココが揃っていないと、コンポーネントをどのような単位でまとめたらいいのかなど
の意思決定ができない。
モジュール性:
構成要素ができる限り独立し、他の構成要素への影響を抑えられているか(例:コンポーネントAの変更がコンポーネントBに一切影響しないか)
再利用性:
既存の構成要素を他システムへ再利用できるか
(例:作成したマイクロサービスを他の事業でも再利用して共有サービスとして利用できないかetc)
解析性:
影響範囲や修正箇所、問題箇所などを解析できるか
修正性: 別名【変更容易性】とも呼ばれている。
品質を保ちつつ効率的にプログラムを修正できるか
(例:仕様を更新する際に、すでに作成したものへの影響をどの程度抑えた状態で対応できるか)
試験性:
品質を保ちつつ効率的にテストを行えるか(例:明確な合否基準を設定できるか)
静的解析と動的解析
パフォーマンスなどは、動的解析も静的解析も可能だが、保守性に関しては、
動的解析を行おうとするとコストもかかってかなり大変。
そのため、構造の側面からの静的解析で対応するのが現実的であるという。
たとえば、「設計原則の中でこれを強く満たし、この原則は満たさなくていいものとする」といった表現のように。
静的解析は、ドメインモデル図に対して行った上でだとわかりやすいと個人的にも思っている。
ただしそれは、ドメインモデル自体がドメイン貧血症ではない状態である場合の話。
テストの品質
上記の試験性がこれに該当する。
たとえばテストコードが異様に長いということは、そのテストには責務が複数混在している可能性が高い。
そうするといくらTDDでやっていても、そのテストコードを通るように実装していても、
テスト対象のプロダクトのコード自体は、単一責任を満たすことは難しい。
テストが長い⇒テストの責務が複数の可能性大⇒テスト対象が単一責務違反
テストコードを見て、それが何をテストしているのか?
責務を一言で言えない、責務が曖昧であるとか、認知負荷が非常にかかる場合には、
テストコード自体を意味のある単位に切り分けるなどをする。
リファクタリングで設計原則の理解を深める
理論として設計原則を学び、実践としてリファクタリングを行う。
再度理論として、設計原則に戻ってくるという このサイクルを何度も回す中で、
徐々に「この原則は満たし、あれはあえて破ろう。なぜなら~」といった
深い設計の議論が可能になるという共感しかないお話しがあった。
ドメインモデル図を描き、良い設計を心掛けていれば、
自ずと何かしらの設計原則を満たすようになっており、同時にどの原則には反しても許容されるという判断がつくようになってくる。
ビジネスとアプリケーションを繋げるモデリング
モノタロウさんの尾髙さんのLTです。
業務理解を促進しつつ、ドメインモデルに変換する際に使用されている4つのモデルが紹介されていました。
ビックピクチャーモデル図
全体像をマクロに見られるモデル。
これはビジネス全体感を理解するために、イベントストーミングなどを用いて、
とりあえずハッピーパスのみとかだけ可視化するとかで、業務の理解を促進。
コンテキストマップ
下図のようなマクロなコンテキスト境界を定義したモデル図。
ここでは、システムの構成要素におけるコンテキストという意味ではなく、
あくまでも業務領域間の関連を表すマクロなコンテキスト図のことを指す。
これは神崎さんが提唱しているRDRAで作成できるコンテキストモデルのことをもろに表す。
ただし、このコンテキストマップはまだ業務理解が浅いうちには
どこで境界を定義したらいいのかわからず、後述のプロセスモデリングまで
行わないと不明な部分もある。
そのためわからない部分は、プロセスモデリングに進んでまたこのコンテキストマップに戻ってを繰り返す。
そうやって境界の位置を定義しなおす。
プロセスモデリング
ここで言われていたプロセスモデリングとは、BPMのことをもろにさしていた。
ビジネスにおける振る舞いの部分にフォーカスしたモデリングである。
いきなり5W2Hとかでモデリングすると、底なしに概念が出てきて本質を見失いかねないので、よく皆さんがやられている手法は、イベントストーミングで、コトの流れに着目する方法。
ドメインモデル図
データと処理がまとまった説明の必要もないモデル図。
しかし登壇者の方曰く、このモデル図だけアプリ的な要素が強く感じられるそう。
値オブジェクトだの、エンティティといった用語はビジネスサイドのステークホルダーからしたら「は?」ってなってしまいます。わかりますこれ。
登壇者の方の工夫 -概念構成図-
イベントストーミングでは時系列の流れに沿ったモデリングをしていながら、
ドメインモデル図になった瞬間、静的な構造になるというその変換がどうやらチーム内で苦戦したそうです。
これは以下の書籍でも語られていましたが、ドメインモデルは構造の静的な側面であって、縦に存在しているものだとしたら、ユースケースやサービスといったものは、その縦に対して直行するようにしてまたがっているからだと思われます。
そこで概念構成図という、ICONNIX手法の簡易ロバストネス図のようなモデル図を描き、
構造に変換しやすい思考プロセスとして使われたそうです。
概念構成図
ステップ1 プロセスモデリング
これはアクティビティ図などでも代用できそうではあるものの、
それだと正直、個人的には集約の範囲がどこなのかなどの考察がしにくいです。
自分がその対象ビジネスの知見が深いなら、暗算のように集約を発見できますけども。
また、エヴァンス本では、ポリシー系の概念をモノやコト系から分離するまでに
めちゃくちゃ長い工程を経ていましたが、イベントストーミングの利点は、
ポリシー系の業務ロジックを最初から関心分離している点ですね!
ポリシー系を柔軟に迅速に変えられるかが、変革のキーとなるわけだし。
ちなみにこのプロセスモデリング前に、ざっくりでもいいから概念図を描いておくと、考えやすいです。
※この概念図っていうのは概念データモデルではないです。
超未完成版の概念データモデルくらいに思っておいてください。
ステップ2 操作の割り当て
下図を見てください。
ユースケース駆動のモデリングで代表的なICONIX手法で出てくる、
ロバストネス図に似ていませんか?
見比べてみてください。下図がロバストネス図です。
ロバストネス図の利点として、
単一の責務になるような画面オブジェクトを見つけやすい
操作の割当先であるエンティティの考慮漏れを防げる
などがありますが、正直図がめっちゃ縦長になりやすく、後からモデルを変更する時にも面倒という短所もあります。
そのため、ユースケースの1段階細分化した操作に分割し、
それがどのデータを必要とする操作なのか?を考えた上で、
そのデータが置かれたエンティティに割り当てるということを端的に表現した最初の図の方が、モデルとしてはコミュニケーションが取りやすいです。
ステップ3 主要属性の洗い出し
このステップ3で何をやってるかというと、ステップ2のエンティティ内のどの属性を操作してんのか?という1段階詳細化されたモデルになってます。
ようは、ステップ2のモデルの検証にもなるモデルを描いてるわけですね。
ここでいうリードモデルとは、UML的には派生属性というものであり、
他の属性を組み合わせて計算することで出てくるものを指します。
例えばですが、合計受注金額などはもう名前からして、それだってわかりますね。
ちなみに説明はされていませんでしたが、大前提として
操作の割当先の考え方として、情報エキスパートパターンを使いこなせないといけません。
正しいエンティティ先に操作を割り当てたのに、「ん? この操作がこのエンティティにあるって名前の意図的におかしい」と感じたら、上記の概念モデルに戻ってください。データが高凝集にまとまっていない可能性大です。
情報エキスパートン関しては以下に参考記事を載せておきます。
個人の見解
イベントストーミングで業務の流れを理解し、そこに登場するデータの側面も議論する。
ER図だけでなく、DFDなども用いると、さらに業務理解も深まるし、
関連性の高いデータの集合(サブジェクト)がどの範囲までかも理解しやすいと感じる。
そのデータを高い凝集になるように概念データモデル図などを使ってまとめたら、
そこに情報エキスパートに従って、シーケンス図やロバストネス図などを用いて処理を割り当てていく。
その際に概念図の静的側面とシーケンスの動的側面の整合性を取ることは忘れずに。
情報エキスパートに関しては以下の記事を参照ください。
これだけで、だいぶ流れを構造に変換するのは簡単になる、、、が
描くモデル図が多くなってしまうのは難点💦
モデルが変更された際に、それらすべてを変更しないといけないこともあるからである。
これはメンテが大変であるものの、最初自分たちの業務理解が浅いうちは、
たとえ描くモデル図が多くなっても、整合性を取りながら複数の観点で
(構造、動的、状態)モデルを描いて業務理解を深めた方がいいと感じる。
RDRAでは、動的:アクティビティ図、構造:情報モデル、状態モデル、
条件分岐のデシジョンツリーの4つに絞り込むことで、メンテコストを最小限に抑えつつ
業務理解を促進する試みが盛り込まれていると感じる。
しかしながら、基本はモデル図はつくってもいつでも簡単に捨てるスタンス
これは、以下のアジャイルモデリングという書籍でも触れられているマインドである。
是非DDDやってるのなら読んでみてほしいです。
松岡さんLT
スクラムやDDDをうまく機能させるためのコミュニケーション、
スクラムの価値基準である【尊敬】【マナー】について語られていました。
アジャイル脳とウォーターフォール脳では、そもそも人の脳のOSがあっていない状態ゆえ、
話がかみ合わず、尊敬が損なわれ、せっかくのDDDなどの効果が薄まってしまうという内容でした。
実体験として思い当たることがあったので、かなり胸に響きました。
アイデアフレームワーク
DDDなどのハードスキルをうまく機能させるためのフレームワークを紹介されていた。
マナーというソフト面の要素とDDDやスクラムといったハード面の要素が互いに支え合う力学関係になったフレームワークであると感じた。
個人の見解
このお話は、自分の体験に照らし合わせた際、過去の反省をするキッカケにもなりました。
過去の複雑系のビジネスにおいて、ウォーターフォール脳になってしまっているチームメンバーに対して、頭ごなしに「この領域は不確実性が高いんだから、なんでその前提を疑えないスタンスなんですか! 何で個別最適な解決策に飛びつくんですか!」と怒りをあらわにしてしまう場面がありました。
結果的に、完成したモデルは、モデルとしての出来栄えは良かったと今でも感じるものの、
その完成形に至るまでの心理的安全性は決して高いと言えない空間をつくってしまっていたと感じます。
これは今になって思えば、自分自身がチーム全体に対して全体最適な視座を損なわせる作用をしていたと感じます。
さらに自分自身が相手に対してのマナーの部分でウォーターフォール脳になっていました。
知情意の中で、完全に【情】を失っているトランス状態ですね💦
今年は特に、この情というソフトスキル部分を磨かないとダメだなと感じる出来事が続いたため、だから尚のこと胸に刺さったのかもしれません。
どんなに技術的なハードの部分をアジャイル脳にしたとしても、
チームメンバーや顧客に対するマナーという部分で、アジャイル脳に慣れていなかったと強く感じます。
モデリングやDDDなどのハードスキル部分でのアジャイル脳
マナーや尊敬・勇気あっての対話をする際のソフトスキル部分でのアジャイル脳
両方あって初めてアジャイル脳
ということに改めて気づかされた気がします。
増田さん交えたディスカッションタイム
リファクタリングの判断
ツールなどを用いて定量的にリファクタリングすべきかの判断をするのもいいが、
増田さんはどっちかというとボーイスカウト原則を体現されている印象です。
コードの嫌な臭い、これは本当に感性に近いものに感じるが、
ぶっちゃけ【慣れ】で「なんかこのモジュール、名前が付けにくいな」とか、
「なんかこの処理がここにあると、モジュール名と違和感あるな」とか、
「なんか意図を把握するのにめっちゃ時間かかるな」という、
この「なんか~だな~(モヤモヤ)」という感覚が非常に大事
これは何度も汚いコードを修正したり、モデルを何度も描きなおし、洗練していく活動をするうちに勝手に身についてくると個人的にも感じている。
大規模になってきて計測の必要性が出てくるまでは、
「なんかやたらこの部分仕様変更する時にコミュニケーションコストかかるな」
「なんかやたらリリースまでの時間かかるなあ」
「なんかこの部分やたらテストのコストかかるなあ」
という部分は、ボトルネックになっている可能性が高いため、そこが技術的負債の原因になっているかもしれない。
ボトルネック箇所は常に変化するため、そこをモニタリングするのも大事だが、
肌でそこを感じ取るこの【コードの不吉な臭いを感じ取る感性】も非常に重要。
トレードオフを解消したビジネスモデル
非常に衝撃を受けたのは、以下の図のビジネスモデルである。
サプライチェーン全体のマネジメントが素晴らしいと率直に感じた。
従来では何がトレードオフであったかというと、
在庫を過剰にかかえるとコストかかる
しかしながら、
在庫を抱えないと顧客数の拡大ができない
そのトレードオフを解消したビジネスモデルが上図のモデルだ。
TOC(制約理論)では、スループット会計の考え方を活用し、在庫点数を制御して、必要な物を必要な時にという物流マネジメントをする動きが求められる。
そのため、背後のメカニズムとしてTOCではないものを感じました。
目的はそもそも【利益最大化】。
考案者の方は意識してそのトレードオフを解消するアイデアを創出したのかはわからない。
ただ、TOCのクラウド法などと他の利益最大化の思想とを用いることで、ある程度は属人化を排除して
イノベーションを起こすようなビジネスモデルのアイデアを創出できそうと感じた。