オブジェクト指向設計実践ガイド読書会 - 第41回 === ###### tags: `オブジェクト指向設計実践ガイド読書会` # 開催概要 * 日程: 2022/11/19 Sat 21:00〜23:00 * 会場: https://discord.com/channels/432531367427964929/898843794101911622 * [README](https://hackmd.io/sSmTRzcQSCuvqiO7uDUkFg) * [タイムキーバー用テンプレート](https://hackmd.io/E0HZBN9OS9GBAtnsYXjDsw) ## 課題図書 『オブジェクト指向設計実践ガイド ~Rubyでわかる 進化しつづける柔軟なアプリケーションの育て方』(Sandi Metz 著, 髙山泰基 訳, 技術評論社) - 技術評論社, pdf版あり - https://gihyo.jp/book/2016/978-4-7741-8361-9 - Amazon - https://www.amazon.co.jp/dp/B01L8SEVYI ## 実施要領 - 事前読書なし。都度その場で読んで、感想を書いて、議論する、を繰り返す。 - 参加スタイルは自由形。チャットでも音声でもご自由に。 - 主催はチャット参加です。 ## タイマーについて 時間管理はタイマーbotで行います。 VCチャンネルに入っている人を対象にメンションが飛ぶので、VCチャンネルへの参加をお願いします。 また、タイマーは終了時に **音声がなる** ので、ご注意ください。 ## 当日までの準備 1. 課題図書を手元に用意する - 買う、借りる、etc(?) 2. 当日までに読んだり読まなかったりする - 当日その場で読むので、事前に読んでおく必要は無し - 気になったら事前に読んでおいても良し --- # 当日の進行 ## 進行フロー https://hackmd.io/sSmTRzcQSCuvqiO7uDUkFg?view#%E9%80%B2%E8%A1%8C%E3%83%95%E3%83%AD%E3%83%BC ## :goti: or :okawari: について - 各パートごとに :goti: or :okawari: を投票する. - :okawari: が1つでも有れば、パートを続行する. ## 開催コール https://1.bp.blogspot.com/-YrhlmWQ4uIQ/UrlmxoUdDeI/AAAAAAAAcLw/M6VFUKHnTos/s400/text_start.png ## タイムキーパー募集 https://hackmd.io/E0HZBN9OS9GBAtnsYXjDsw#%E3%82%BF%E3%82%A4%E3%83%A0%E3%82%AD%E3%83%BC%E3%83%91%E3%83%BC%E5%8B%9F%E9%9B%86 ## 読書パート https://hackmd.io/E0HZBN9OS9GBAtnsYXjDsw#%E8%AA%AD%E6%9B%B8%E3%83%91%E3%83%BC%E3%83%88 ## 投票パート https://hackmd.io/E0HZBN9OS9GBAtnsYXjDsw#%E6%8A%95%E7%A5%A8%E3%83%91%E3%83%BC%E3%83%88 ## トークパート ### 議論(:thinking_face:)パート https://hackmd.io/E0HZBN9OS9GBAtnsYXjDsw#%E8%AD%B0%E8%AB%96%E3%83%91%E3%83%BC%E3%83%88 ### 任意トーク(:+1:)パート https://hackmd.io/E0HZBN9OS9GBAtnsYXjDsw#%E4%BB%BB%E6%84%8F%E3%83%88%E3%83%BC%E3%82%AF%E3%83%91%E3%83%BC%E3%83%88 ### 次回繰越(:eyes:)パート https://hackmd.io/E0HZBN9OS9GBAtnsYXjDsw#%E6%AC%A1%E5%9B%9E%E7%B9%B0%E8%B6%8A%E3%83%91%E3%83%BC%E3%83%88 ## 終了コール http://3.bp.blogspot.com/-zgTNWF_hBmI/UZYlh9RhuDI/AAAAAAAATQ8/dymPl5P4eAs/s500/undoukai_relay_animal.png # 読書メモ ## 8.4_コンポーズされたBicycle_p.224_228 ### discord開始地点 https://discord.com/channels/432531367427964929/898843794101911622/1043497480052019220 ### 感想 - OpenStruct は Ruby3.0 で非推奨になったのでこれからは使わないのがおすすめ :+1: :+1: - https://zenn.dev/tyanakaz/articles/1d9a3f05165c31 - https://zenn.dev/jnchito/articles/24e0bd7fd1045d#openstruct%E3%81%AF%E3%81%AA%E3%82%8B%E3%81%B9%E3%81%8F%E4%BD%BF%E3%82%8F%E3%81%AA%E3%81%84%E6%96%B9%E3%81%8C%E3%82%88%E3%81%84%E3%80%81%E3%81%A8%E3%81%84%E3%81%86%E5%85%AC%E5%BC%8F%E8%A6%8B%E8%A7%A3%E3%81%8C%E5%87%BA%E3%81%95%E3%82%8C%E3%81%9F - 継承から集約に置き換えたことで異なるバリエーションのオブジェクト生成は容易になった一方で、「特定種類のBicycleは、xxについて固有の振る舞いを持つ」といった拡張をもたせる余地がかなり限定された(config経由でしか差異が作れない)、という側面もある - これについてどういう評価を下すのか、次節に注目(この節では「オブジェクトの生成は容易になった」という言及しか無いので)(次節で分からなかったら :thinking_face: :bomb:) - 継承を選択するか集約を選択するかはプログラミング言語とか目的でもかなり変わってくると思うので期待 ### 疑問 - p.228のコラムで急に「厳密な意味のコンポジション」と「集約」という関係をもちだしてきたが、じゃあ最初から「集約」という言葉を使っておけばよかったのでは……? :point_left: - わざわざ「集約」の意味で「コンポジション」を持ち出して「実は、コンポジションにはより厳密な意味が有って……」というのは、むしろ混乱を起こしたいのかと思ってしまうレベル - そして次のページも「コンポジション」という語が出てくるという。(コラムがなかったことに) - 少なくともUMLはまさにp.228にかかれているような違い(ライフサイクルを同一とするかどうか)によって「集約」「コンポジション」を使い分けている - 本文がUMLに全く触れない or コラムで軽くUMLに触れる程度なら、まあ本文のような進行もわからないでもないかもしれなくもない()が、p.94でUMLにわざわざ言及するなら、UMLの意味に準拠すれば最初から最後 & 読後まで無用な混乱を産まないのでは?というマッチポンプ感 ## 8.5_コンポジションと継承の選択_継承による影響を認める_p.229_p.232 ### discord開始地点 https://discord.com/channels/432531367427964929/898843794101911622/1043503209668415508 ### 感想 > 一般的なルールとしては、直面した問題がコンポジションによって解決できるものであれば、まずはコンポジションで解決することを優先するべきです。 > (中略) > 継承がより良い選択肢であるのは、継承が低いリスクで高い利益を生み出してくれるときです。 p.229 - 基本的には継承よりも委譲だけど継承の方が有効な場面もある :+1: :+1: - 委譲の方がそもそも依存関係はゆるいので安牌になりやすくはあるが、適切な箇所で使えば「一致してなくてはならない振る舞い」が実際に一致していることを担保したり、基本の処理フローは一元化しつつ差異が生じる部分は多態で解決したりと、強力な効果は実際ある - なので基本的に「継承禁止」も「どんどん継承」もナンセンスの類で、本書のように「注意して使おう」「使う時のコストを意識しよう」ぐらいが妥当なライン :point_left: :+1: :point_left: - あとは、「安牌になりやすい」は「安牌である」ではないので(委譲しまくった結果、手続きがとっちらかって、それぞれ独立してるけど総体としてどうなってるかわけわからん、なんてケースもザラ. 委譲を使ってようとしくじれば相応のひどい目にあう) - 多態なんかは、(実装の共有を伴うにせよ伴わないにせよ)階層構造が作られるからこそ幅広い環境で利用しやすい、という面もある - 階層構造無しで多態を実現しようとするなら、(静的型解析の有無によらず)ダックタイピング一択 > 継承では、「自分が間違っているとき、何が起こるだろう」という問いかけが特別に重要な意味を帯びてきます p.231 - 継承で作り込んでオレオレフレームワークになって後で要件が変わって爆死する話、あるある - 一方で、「開発対象の知識をよく表現している」かつ「バリエーションの追加による拡張が容易」で「一部のルールを書き換えても影響範囲が局所的」という、俗に言う「よくできた設計」は、開発対象のモデルを構築して適切な階層構造を作り上げ、ミニフレームワークのような構造になってこそ最大限に実現される面もある :crab: - これは「最初に完璧な階層構造を作りましょう」という話は含意しない. 段階的に「より適切な階層構造」を目指していけば良い話. その過程で継承を避けて集約を優先する、という選択自体は当然ありうる(全面的に集約 or 全面的に継承の二択じゃないので) - なので、継承を利用して作られた階層構造を安易に「オレオレフレームワーク」と揶揄する一部の風潮もどうかと思う - HTTPの仕組みとか、既によくできた既存の仕組みがあるのにそれを全部ゼロから独自で内部向けに作ろうとするなら、それはまあ「オレオレフレームワーク」という言葉で批判されても仕方ないとも思う - 「オレオレフレームワーク」という言葉が一体何を指しているのか、今はほとんどネットミームと化していて、継承批判の例として出すには怪しい気がしている - 継承を安易に使わずに慎重に考えよう、という指針を示す良い問いかけ感 - 「自分が間違っているとき、何が起こるだろう」という問いは継承に限らず、あらゆる技術的決定において一度は考えておく価値がある :+1: - 「やっぱやめた、としたらどうなるか」とか「取り返しがつくか」という問い方を、自分はよく使う - ちょっと脱線だけどモノリス・モジュラモノリス・マイクロサービスの話もこの問いかけをぜひすべきですよね(マイクロサービスはやっぱやめたができない・・・) :+1: :point_left: - ちょうど、「可逆な設計、不可逆な設計、どちらなのか考えろ」と Kent Beck に動画で言われてから参加しました。 :clap: - https://www.youtube.com/watch?v=OPsHw_05FlA > 「利用性が高い」コインの裏面は、サブクラスが複数の型を混合した物の表現であるときの、振る舞いの追加の不可能さです。 p.231 - 「最上位の型」として扱っていたものが本来は持つべきでない振る舞いを持つと、そのクラスを基底として拡張するのが難しくなるというのは経験してるので「これマジヤバいわ~」ってなった。 :aruaru: - 構造自体はそのクラスの上位クラスを作ってしまえば誤魔化せはするんだけども、クラス名が既に限りなく抽象的な名前だった時はその手すら使えなくなる。(どちらにせよ破壊的変更を加えることになるので、設計としては良くないことになる) - つまり、そのクラスが表現する領域についての知識・理解が無いときに陥る可能性が高い問題であるといえると思う。(ママチャリ以外の自転車が存在していないと思っていたらマウンテンバイクとかロードバイクとかいろいろありました。的な) :+1: :+1: - 情報が十分に出揃っていないとき、どんな種類のバリエーションが有りえて、今後どういった種類が有り得るのか、自信を持てない時は継承を避ける(継承を使うにしても、I/Fのみにする)というのは、有力な判断 :+1: - 実際、「一般にこういう構造が見いだせそうだが、前提情報がどの程度バラけるかはあやしい」という時は、かなり広くとった必要最低限のI/Fだけ要求して、細かい実装は共通化せず個別クラスで頑張る、ということもときどきやる :+1: :+1: - 一般人が使うようなアプリケーションソフトウェアなら内部のコードが見えないからいいんですけど、ライブラリとかの開発だとこの判断を間違えるだけでとんでもない変更を行わないといけなくなって大変なことになる(ライブラリの利用者全員に影響)ので、こういう「必要最小限度」で少しずつ抽象化するような手段をとるのは大事だと思いました。 :+1: :+1: ### 疑問 > 次のようなフレームワークは避けねばなりません。ユーザーがその振る舞いを手に入れるために、フレームワークのオブジェクトを継承しなければならないようなフレームワークです。 p.232 - 言いたいことはわかるけどちょっと主語が大きい気が? :point_left: :point_left: - これを言っちゃうと大体の gem・フレームワークがだめでは? - FW側が「これを継承(実装)して使ってね。」と言ってくるパターンはかなり多いので多分軒並み壊滅しますね。(Microsoft系のGUIは基本死ぬと思います。) - > ユーザーのアプリケーションのオブジェクトは、すでにそれ自体の階層構造で構成されているかもしれません。皆さんが書いたフレームワークからは継承できない可能性があるでしょう。 - ここから推測するに既存のコードを拡張していく際のことを言いたい? - Controllerとかいちいち自前で実装したくないので、そういうのは継承で良くね、感ある. 自分たちに必要な箇所だけ書いて、後は丸投げで済ませたい. - FWと自分たちのアプリケーションとを仲介するような層(Controllerとか)はFWとべったり仲良くなっても大した問題にはならない(どうせFW依存は避けられないのだし. 暗黙的か明示的かぐらい) - 一方で、アプリケーションの中核となるようなモジュール群までくまなくFWのモジュールを継承することを強制する or 前提とするようなのは、ちと使いづらい - J2EEみたいなの想定しているのかな? - なので、FWとやり取りする層と自分たちで作り込んで守りたい範囲とを、ある程度分けられるFWなら良いんじゃないかな、感 ## {読書範囲} ### discord開始地点 ### 感想 ### 疑問 --- # ふりかえり - 感想/次回の課題それぞれで5分 - 要望に応じて :okawari: ## 感想 https://hackmd.io/E0HZBN9OS9GBAtnsYXjDsw#%E6%84%9F%E6%83%B3 ### 気づいたこと、気になったこと - 継承は諸刃の剣であることを改めて実感できた。(上手く扱えれば本当に強力な仕組みだと思う。) :+1: - p.229における継承とコンポジション(集約)との対比は、一つの側面であって全てではないが、両者の差異の一部をある程度うまくまとめられているように思う :+1: :+1: - 階層構造のコストを払って、構造化による自動化・簡略化を取るか - 手作業での委譲コストを払って、モジュールの独立性を優先するか - トータルで、安易な継承否定にも継承礼賛にも走らなかったのは良い点 - イベント梯子したら同じ話題が出てた。あるあるな課題だなぁ。(可逆、不可逆の見極め) :aruaru: :+1: :aruaru: - 今日は著者へのヘイトもたまらず平和な回だった(集約の話?知らない子ですね・・・) :zany_face: - 「コンポジション、実はちょっと難しい話もあるんだよ」的なコラムのマッチポンプ感(難しくしてるのはおまe(ry ### 疑問点 ### 仕事に活用してみたいこと ## 次回の課題 https://hackmd.io/E0HZBN9OS9GBAtnsYXjDsw#%E6%AC%A1%E5%9B%9E%E4%BB%A5%E9%99%8D%E3%81%AE%E8%AA%B2%E9%A1%8C [まとめ用mdに追記](https://hackmd.io/wfDfaf4nRQuPG1BYtcy_jA) # 次回 https://hackmd.io/gbQ3_3gcQO-3cGbjLOe21A?edit