勉強会『成長し続け、変更を楽に安全にできるソフトウェア設計とは』のまとめ

こちらの勉強会にオンラインで参加しました。
bpstudy.connpass.com

Twitterハッシュタグ:#bpstudy

非常に勉強になったので、まとめさせていただきました。抜けている部分だったり、不正確な部分もあるかとは思いますがご容赦ください。


●ミノ駆動さん 「混ぜるな危険」を推進する設計
命名や設計パターンはただコードをきれいにするためにあらず、異なる概念を仕分けする道具である。
・ソフトウェアには中心的に存在するモデルがある。それは色々なユースケースと結合しやすく、巨大化しやすい(例:商品モデル)。状態によって振る舞いを切り替える分岐が爆増しがち → 責務がおかしいんじゃないか? → 何か違うものが混じってるのが見えてくる
・単一責任原則に従い分割しようとするのがセオリーだが、知らない人は気付けないし、ことの重大さが分からない。何の観点も道具もないと違いを認知できない。→ 名前設計(命名)、設計パターンが道具として有用。
・商品を例えば予約品、注文品、在庫品、発送品と各ユースケースごとに分割していく。
・First Class Collectionパターンを例にした名前改善の過程の話(うまくまとめきれませんでした)
・買い物カゴに追加するものは、商品ではなく注文品では?
・名前に改善の余地が見つけて明確な名前に変更すれば、余計なロジックを排除できる(例:Products → ShoppingCart)。概念取り出しのヒントにもなる。
・「混ぜるな危険」を解消し、さらに純度の高い概念を蒸留していけば、より本質的な概念が見つかる。
・『現代思想入門』千葉雅也著。アクチュアル(現働的)とヴァーチャル(潜在的)。存在の脱構築
・物理的なものだけで捉えるのではなく、全てのものが複雑な関係性を持っているという解釈で考えると、考えの発展が生まれる。解釈を噛み砕いていくと、全く違う概念が見出される。
モデリングのスキルが熟達していないと、単なる物理的なモデルとして解釈してしまう。それだとモデルが複雑化し、いろいろな弊害が発生する。
・目的単位で役に立つ形でモデリングすれば、モデリングする対象とモデルの関係は1対1ではなく、1対nの関係になる。
RPGツクールの例:村人や宝箱はどういうオブジェクトで表現されているのか? → 両方ともGame_Eventとして表現されている。見た目が違うだけでメッセージ表示やアイテム入手など、ゲーム中のイベントを発生させるオブジェクトとしては変わりがない。
・法的な有効性を発揮できるなど、機能性に大きく貢献する「深いモデル」を見出すためには、リファクタリングを繰り返していくのが大事。

●増田亨さん 設計の学び方 自分流のススメ
・設計を学ぶのは自分のため。
・「正しい」学び方があるわけではない。カリキュラムを学ぶとかそういうことではない。どう学んでも良い。
・設計の学びに特定の到達点はない。
・どこに向かうか、どこまで行くか、どうやるか、どこでやめるかといったことは自分勝手に決める。
設計スキルはさまざまな経験のかたまり。知識だけではない。新しいものに取り組むたびにいろいろな経験が増えていく。一方で闇雲に学ぶのはどうかとは思う。
・どの設計スタイルを学ぶか/経験するか(例:トランザクションスクリプトドメインモデル)
・何を学ぶと良いのか。大事のは設計の結果と過程(before/afterの実体験の積み重ね)。
・知識を頑張って覚えれば設計スキルが上がるわけではない。自分で設計してみてbefore/afterを経験していく。
・設計の学び方:1.上達する 練習して変化する 2.成長する 時間をかけて変化する 3.ひらめき 突発的に変化する → これら三つを並行して進める。
・1.上達する 練習して変化する:ぎこちない動作から始めて、無意識に体が動くようになるまで練習する。リファクタリングカプセル化契約プログラミング、自己文書化 etc.
・2.成長する 時間をかけて変化する:一番重要だと思うのは、見る範囲を広げること。最初はぼんやりとしたイメージで良い。アプリケーション全体としてどうなっているのかに目を向ける。企画の段階なども含め、ライフサイクル全体に目を向ける。アプリケーションが対象とする業務はどのようなものか。どういう価値観でこのソフトウェアが開発されているのか。年単位でいいからつながりで理解できるように(つながりの有無、強弱、遠近、経路)。
・成長の手がかりを増やすため、本から学ぶ。全部は読まずとも、積読、文脈の把握、あらすじ読み、気になるところだけ読む、しばらく経ってから読み直し 等。
・観察と実験:主要な構成要素は?どうつながっている?どう変化する?自分の手でやってみる。コードで実験とか。
・3.ひらめき 突発的に変化する:その時ひらめかなくても、自覚できない潜在的な学びは増えている。行き詰まるところまでやってみる。

●フリートーク
・5000~10000行のクラスが当たり前の泥団子のプロジェクトを、色々な本を参考に直していったら再現できなかったバグが綺麗さっぱり消えた。読みやすくしている程度のつもりだったのが、どんどん解消されていった。その経験がオブジェクト指向設計ドメイン駆動設計にのめり込んでいったきっかけ。
ドメイン駆動設計に登場する「深いモデル」というものに感銘を受けている。今まで全く考えていなかった本質的なモデルの発見。自分達にはまだ見えていない概念が隠れているはずだと信じてリファクタリングしている。なかなか答えが出ないこともあるが、急に閃いたりすることもある。
・レガシーコードは名前が嘘をついていることが多い。
・目的ベースでコードを組み立てていく。その目的を満たすための概念とはどのようなものか?物理的な制約を外して考える。
・抽象化には目的がある。抽象化がうまくいかないのは、目的の整理がなされていないことが一つの問題。
モデリングとは簡略化。うまくなるには、本の要約とかいいと思う。例えば2ページ制限でまとめてみる。書籍の前書きは要約、論文のアブストラクトは文字通り抽象。そういうものを読んで、要約とは何かを学んでいく。あとTwitterとか:「これTwitterの140字にまとめらんねえかなあー」。要約ができないのは捨てられない時。思い切って捨てる。捨てたものがすごく大事なものだったとしても学びはある。
ドメイン駆動設計の端的な良さ・メリット:複雑なフレームワークに振り回されずに済み、アプリケーションの目的にフォーカスできる。変更を楽に安全にできる。ドメイン駆動設計に振り切った方が結果が出る(裏を返せば中途半端ではまずいということかも)。