オブジェクト指向設計実践ガイド読書会 - 第53回 === ###### tags: `オブジェクト指向設計実践ガイド読書会` # 開催概要 * 日程: 2023/04/22 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 # 読書メモ ## 9.6_継承されたコードをテストする_継承されたインターフェースを規定する_p.281_285 ### discord開始地点 https://discord.com/channels/432531367427964929/898843794101911622/1101844560499441674 ### 感想 > 階層内のすべてのオブジェクトがリスコフの原則に従っていることを証明する最もかんたんな方法は、その共通の契約に共有されるテストを書き、すべてのオブジェクトにそのテストをインクルードすることです。 - p.283 - 前章の、「ロールに対するテスト」とアプローチとしては類似 - 要するに、「ロールに対するテスト」自体を共有可能なもの(ex. Mixin)として定義し、同じロールを担うオブジェクトに対するテストで共有しよう、というアプローチ - そもそも「テストを共有可能なものとして定義し、実際に共有する」というアプローチ自体をあまり使ったことが無いが、継承されたサブクラスに対するテストとしても利用可能だろう、というのはなるほどという感じ - 一方で、継承を使う場合には「抽象クラスを継承したテストクラス」をテスト専用に定義して、そのテストクラスをSystem Under Testとして用いる、というアプローチを良く使っていて、割とそれで間に合っていた感 - 「継承を用いたコード」という文脈において、本書の「ロールに対するテスト」を共有するアプローチに比べて「テスト専用のサブクラス」を用いたテストは「共有された実装に対するテスト」という観点ではどういう長所/短所が有るだろう ### 疑問 https://discord.com/channels/432531367427964929/898843794101911622/1101851002660986950 > 契約は、共通のインターフェースに備わっています。次のテストは、インターフェースを明確に 示し、Bicycleとは何かを定義しています。 - p.283 - 「どういうメソッドコールに反応するのか」はわかるが、「インターフェースを明確に示し」ているかは微妙な気がする…… - シグニチャ(メッセージング風に言うなら、受け取るべきメッセージ?)がわからないし、どういう応答をするのか or しないのかも、テストからは判然としない - このテストを通るオブジェクトはすべてこれらのメソッドコールに反応可能なことはわかるが、どのように振る舞うのかはよくわからないような…… - このやり口自体は「インターフェースを規定するテスト」というよりは、静的解析が無い環境での苦し紛れ感の方が、正直強い ## 9.6_継承されたコードをテストする_サブクラスの責任を規定する_p.285_289 ### discord開始地点 https://discord.com/channels/432531367427964929/898843794101911622/1101854860292391003 ### 感想 - ロールのテストをincludeする度に「各ロールテスト用のsetup」を意識しなくてはならないのだとすると、ちょっとつらい…… :joy_cat: ```rb def setup @bike = @object = RoadBike.new end ``` > この要件はサブクラスに課されるものの、実際に制約を課す振る舞いをするのはBicycleです。それゆえ、テストはBicycleTestに直接置きます。 - これは、前節の感想で言及した「テスト専用のサブクラスを定義する」と発想としては近しそう :+1: - 後続のテストで(Ruby的に「抽象クラス」は無いものの、便宜的にそう呼ばれている)抽象クラスのインスタンスを生成しているあたり、「抽象クラス単位でテストする」という発想はやはり同じっぽい ### 疑問 ## 9.6_継承されたコードをテストする_固有の振る舞いをテストする_9.7_まとめ_p.289_293 ### discord開始地点 https://discord.com/channels/432531367427964929/898843794101911622/1101864125845475398 ### 感想 > これらの特化した部位をテストする際に重要なのは、スーパークラスの知識をテスト内に埋め込まないことです。 - p.289 - スーパークラスの存在や実装を前提にしてしまうと、継承ツリーや構造を置き換えた時にテストが壊れてしまうので、リファクタリングあるいはリストラクチャリングが困難になる = 有る瞬間の特定の構造・設計に強く依存したテストになってしまう :+1: :+1: :+1: - ↑に書いたような理由で「スーパークラスの知識をテスト内に埋め込まないこと」が重要だと解釈して、だとしたら同意なのだけれど、本書ではどういう理由で↑のように主張しているのか明言していないような…… - > このテスト内でそれを直接参照することは冗長であり、結局は制限になります。 - の部分がそれっぽいですかね。限りなく少ないテストを書くみたいな思想だった気がしたので。 :naruhodo: :+1: > 幸いにも、設計スキルで問題は解決できます。Bicycleは具象的な特化を獲得するためにテンプレートメソッドを使っているので、通常はサブクラスによって提供される振る舞いをスタブできます。 > ... > 次のテストは、 まさしくそのような戦略をとったものです。1行目で新しいクラスであるStubbedBikeを、Bicycleのサブクラスとして定義しています。 - p.290-291 - 前節までの感想で言及していた「テスト用のサブクラスを定義する」というアプローチが、まさにこれっぽい :+1: :+1: :+1: > . - 最後、まとめの章とかなく、「テスト大事!」といったとこから 1ページのあとがき「メッセージが大事」で終わってしまった。あっけない感じ。 - はんぱない尻切れとんぼ感。もしくは打ち切(ry - 俺たちの設計はこれからだ( - https://images.uncyc.org/ja/6/6b/Yamato.jpg ### 疑問 > RoadBikeTest は意図的に spares メソッドの存在を無視していることを伝えつつ、local_sparesが動作することを保証するべきです。 - p.289 - このあたりの主張は、ロンドン学派っぽい著者としてはそういう主張になりそうな気はしつつ、実際に提示されたサンプルコードのどのあたりで「意図的に spares メソッドの存在を無視していることを伝え」ているのか、よくわからない :point_left: - 実践的には、コメントで補うぐらいでも十分だと思うけど、それも無い…… - 閉世界仮説的な前提なら記述されていることが世界のすべてなので、「記述されていない = 存在しない、ここで言うならばテスト対象ではないことを明示した」と言えなくもないけれど、テストコードの実情を考えると、「記述されていない = 存在しないか、存在するが記述されていないかは未知」と扱うべき。つまり、「伝えていない」。 :desuyone: ## あとがき_p.294 ### discord開始地点 https://discord.com/channels/432531367427964929/898843794101911622/1101871955914801262 ### 感想 > 設計に緊張が伴う理由は、これらの規則を破るためです。 - この辺は「なぜこうするのか」ということを意識しないと難しいと思う。 - その「なぜ」を説明されて理解できなかったらできなかったで規則は無視していいと思う。 - 「規則/書いてあることを盲目的に信じればOK、ではない」と最後に言って終わりたい感じ? :+1: :+1: - 「規則」と言いつつその規則を破らなくてはならないシーンがあるのは何故か、それは「規則」ではなく精々が「いち手法」程度では?という気がしなくもない :+1: - SOLIDはじめとしたの「principle」という語法にも感じるけど、言葉のチョイスが強すぎない?という印象 :+1: - 単一責任原則とか、どの単位で「責任」としてるのかがわからなくて困った覚え…… - 一応、原文では「変更理由が一種類となるようにせよ」と、『Clean Architecture』では「関連するアクターが一人となるようにせよ」と、「責務」という曖昧な言葉ではなくもう少し具体的に説明されていますね :+1: - (という補足を入れる度に、「なんで"単一責任の原則"なんてタイトルにしたの?」と思うアレ):point_left: - 実際のところ、「規則」とか「原則」とかではなく、「経験的に正しいと言えることが多い性質」くらいでしかないものがほとんど。 > オブジェクトを関連づけるのは、それが何をするかではなく、その間で交わされるメッセージです。オブジェクト指向設計はフラクタルです。言ってみれば、問題の核心は、オブジェクトが互いに交流するための拡張性がある方法を定義することにあり、オブジェクトをどの規模でとらえようと、この問題はいつでも見てとれます。 - 「オブジェクト指向プログラミング」を(ストロヴストルップ的な意味ではなく、アラン・ケイ的な意味において)「オブジェクト同士のメッセージングによるプログラミングモデル」だとするのなら、「オブジェクト指向設計」は「オブジェクト同士がどのような/どのようにメッセージングを行うのかを設計する行為」として位置づけられそう - このような意味で「オブジェクト指向設計」を規定するのなら、このまとめは結構良いまとめになっている印象 - そういう意味で、ものに注目するだけではなく、ものとものが関わり合う (相互作用する) 文脈を見つけることが重要。 > オブジェクト指向設計はフラクタルです。 - 再帰的、もしくは、入れ子的ではあるかもしれないけれど、「フラクタル」ではない。 **同じ構造** が再帰的に含まれているわけではない。 :+1: :thinking_face: - そして、この拡大解釈は、結構広く行なわれているので、そのたびに違和感を感じてる ^^; - 「オブジェクト間のメッセージング(についての設計)」というモデルは共通しているでしょうけれど、「同じ構造」かというとそれは疑問(という意味で、「フラクタル」という呼称はたしかにあやしい。再帰的ではるだろうけれど) ### 疑問 > より真相にあるのは、どんなオブジェクトもある意味すべて同一である、という事実です。 - 「より深層」だろうか(^^; - > A deeper truth is that there is a way which all objects are identical, regardless of whether they represent entire appliactions, major subsystems, indivisual classes, or simple methods. - たぶんこのあたり・・・? :+1: - > deeper truth - やはり深層…… - 第二版、後書きも完全に第一版と同じだけれど、なぜ第二版を出したのだろう。(差分が見つからない) :eyes: --- # 本書の感想 - 「理論的なところはかなり弱いが、実践的なテクニックは悪くない」という感想 - 変なところでミーハー臭いというか、扱いきれない概念・モデルを使って説明しようとして、細かいところだと蛇足を生んで説明をややこしくしたり、細かくないところだと破綻した理論(「使われていない受信メッセージ」とか)を作ってしまったりとかしてしまっていた印象。 - ただ、個別の具体的手法は実践的だったり、参考になるところもあったりする。テストにおける「ロールに対応するテストを定義して、それを各実装クラスのテストで共有する」というのは、細かいところで気になる点はありつつも、発想としては持っていなかったので参考になった。 - 改めて誰かに紹介するとしたら、「個別のプログラミングテクニックは参考になるよ、でもその根拠として書いている理論的・概念的な部分はあまり真に受けない方が良いよ」という紹介の仕方をするかも。 - ~~「メッセージング」のイメージを掴みたかったら、この本読むよりSmalltalk-72触った方がよっぽど早いまである~~ - 著者の経験による実践がまずあり、それを説明付けるために「がんばっちゃった」という感じかしらね。 - 扱おうとしている観点は悪くないけれど、著者の思い込みや説明不足などでうまく生かし切れていなかった印象。執筆に当たっての客観性と作文力があったならば、あるいは。 - 無条件で薦めたい本ではないけれど、類似する本を複数読み比べる一つに加えるくらいなら候補にしてもいいかな、くらいの評価。 :+1: - Ruby でこういう分野の本がこれ以外にないのがのう・・・ :joy_cat: :sorena: (オブジェクト指向に限ったものではないけど最近出た研鑽Rubyとかはある・・・けど・・・) - 『研鑽Ruby』はOOPというより題名通りRubyプログラミングのテクニックおよびその背景という感じが強い感じではある :desune: - 知らないことがかなりたくさんあったので学びは多かった。 - ただ一人で読んでたらどうなってたかわからないので本書の感想として扱うべきかは謎。(読書会の感想になってるソレ) - 何回も輪読会に参加している書籍だったけど読むたびに、そのときの参加者によっていろいろな観点での見方を得られて面白い(この書籍に限ったことではないけど :+1: - だいぶ参加したり、しなかったりだったけれど、一通り背景にあるだろう考えを議論しながらの読書会できたのは良い体験。 :+1: ## 次回の課題 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) # 次回 おしまい
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up