オブジェクト指向設計実践ガイド読書会 - 第47回 === ###### tags: `オブジェクト指向設計実践ガイド読書会` # 開催概要 * 日程: 2023/02/11 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.2_受信メッセージをテストする_使われていないインターフェースを削除する_p.249_251 [前回](https://hackmd.io/ReWH-TMHRP6JeF9SIlHK1w?view#92_%E5%8F%97%E4%BF%A1%E3%83%A1%E3%83%83%E3%82%BB%E3%83%BC%E3%82%B8%E3%82%92%E3%83%86%E3%82%B9%E3%83%88%E3%81%99%E3%82%8B_%E4%BD%BF%E3%82%8F%E3%82%8C%E3%81%A6%E3%81%84%E3%81%AA%E3%81%84%E3%82%A4%E3%83%B3%E3%82%BF%E3%83%BC%E3%83%95%E3%82%A7%E3%83%BC%E3%82%B9%E3%82%92%E5%89%8A%E9%99%A4%E3%81%99%E3%82%8B_p249_251)の繰越から ### discord開始地点 ### 感想(繰越) > p.249: 受信メッセージは、オブジェクトのパブリックインターフェースを構成します。外の世界へ示 す顔(face)です。アプリケーションのほかのオブジェクトが、そのシグネチャと戻り値に依存し ているため、これらのメッセージはテストを必要とします。 - メッセージ (しかも「受信」メッセージ) とメソッドの同一視のせいか、意味を読み取るのに初見で首を捻挫した - 「受信メッセージは、オブジェクトのパブリックインターフェースを構成」 - 「受信メッセージに応じて起動されるメソッドは、〜」かな。受信可能なメッセージの定義はプロトコルを定めるけれど、ここでいうインタフェースを定めるものなのだろうか。 - 「ほかのオブジェクトが、そのシグネチャと戻り値に依存している」 - メソッドに依存しているならその通りだけど、(本来の意味での) メッセージに依存しているとするならば、シグネチャとかメッセージ処理機構の実装に直接的に依存するものなのだろうか。 > p.251: 依存されてなさそうな受信メッセージが見つかったならば、 - [トークパート](https://discord.com/channels/432531367427964929/898843794101911622/1073940870895775844) - (本書での用法はおいておいて) 普通の捉え方としては、「依存されてない受信メッセージ」は存在しないのでは。 :tashikani: :thinking_face: - 「受信メッセージ」「送信メッセージ」は、あるメッセージを受信した側から見たとき、送信した側から見たときの呼び方。 - とすると、受信メッセージなるものが存在するならば、それはなにものかが送信したものであるはず。 - ならば、いかなる受信メッセージも、送信者が存在し、その送信者に依存されていると見做されるのが妥当。 - 「メッセージ」という観点に立って説明するなら、「誰にも受信されない送信メッセージは削除されなくてはならない」とかになりそう。だが、そうすると「メッセージ = メソッド(呼び出し)」という世界観では成立しない説明になるという(^^; (単なるNoMethodErrorじゃん、という) - 「メッセージ」「メッセージング」を「メソッド」「メソッド呼び出し」の類義語ぐらいにしか認識しないで説明しようとした弊害が如実にあらわれている箇所 - この奇異に見える文章は、 オブジェクト間で送受可能なメッセージと、 受信側のオブジェクトに備わっているメソッドを 同一視することによる歪みに起因しているように思える。 :point_left: - さらに、コードレベルでは、メソッド本体のコードも含めて「受信メッセージ」と呼んでいるように読める。 → 次回繰越 - それはメッセージを受け取った時の振る舞いであって、メッセージではない。 - 百歩譲って、メソッド呼出しをメッセージ送出と同一視することができたとしても、メソッド定義をメッセージと同一視することには同意しかねる。 :+1: :thinking_face: > p.251: 受信メッセージには、必ずそこに依存するものがあります。表 9.1 に見て取れるように、これは diameter、gear_inches、ratio について成り立っています。(ただしそれらが受信メッセージで あるところで)。 - [トークパート](https://discord.com/channels/432531367427964929/898843794101911622/1073945406171529287) - 日本語でおk - 素で意味がわからないんだけど、原文ではどうなってたのか。 :thinking_face: - > Incoming messages ought to have dependents. As you can see from Table 9.1, this is true for diameter, gear_inches, and ratio where they are incoming messages. - 翻訳し直すなら、「受信メッセージには依存元が存在するはずです。表9.1で確認できる通り、受信メッセージである `diameter`・`gear_inches`・`rtaio`においてこれらは確かに成立しています」という感じ? - 関係副詞や関係代名詞を「〜のところで」とか「〜のところのもの」って訳すの、久しぶりにみた(60s~70s以前ぐらいの古い翻訳だと、たまに見た記憶) ### 疑問 ## 9.2_受信メッセージをテストする_パブリックインターフェースを証明する_p.252_253 ### discord開始地点 https://discord.com/channels/432531367427964929/898843794101911622/1073950621335572580 ### 感想 > p.253 この問題を生み出す結合はGearの内部に隠されています。 - 「テスト=ドキュメント」とは言えない例になりそう? :+1: - この、内部が密結合になっているパターンはどうやって防げば良いのだろうか。テストを書いてリファクタリングしやすくする程度でしか対策できないのか? :eyes: - そもそも気にしなくて良いケース、というのもあるのではと思う :+1: - 密結合な「内部」が完全に内部に閉じていて、オブジェクトの外からは全く関知の術が無いケースとか - この場合、密結合な「内部」はインターフェースによって完全に隠蔽された詳細でしか無いので、使う側がいちいち気にすることではない - 下手に分離して疎結合にすると疎結合にするメリットよりデメリットの方が上回りそうですね。(このメリットが密結合になっているべき理由といえそう?) - 少なくとも、気にしなくていいケースであることすら判別が難しい場合もあると思うので、クラスの内部構造を表現する何か(できれば図)は作っていた方が良さそうですね。 :+1: - 密結合であるべきでない密結合を、コードの再利用以外で検出するとしたら: :+1: - クラス・オブジェクト間の依存関係を図に起こして、想定していなかった依存関係になっていないか確認する - 設計の前提となったドメインやユースケースを確認して、それらを実現するための妥当な設計になっているか確認する - とか? - 確認した結果、密結合になっているべき理由があるなら、それはそれでOKだと思う > p.253 1つはテストの実行時間です - Rails + RSpec + FactoryBot だと大量に依存のあるモデルは DB のレコード生成が大量に発生してめっちゃ遅くなることあるある :aruaru: - レコード必要ない場合は build_stubbed とか build をつかってくれ〜 > Wheelの作成コストが高い場合、Gearのテストは、たとえWheelに関心がなくてもそのコストを払うことになります。 - p.253 - ここで言う「生成コスト」は、前後の文章から「オブジェクトの生成にかかる時間」だけを指しているっぽいが、「生成するために必要な手順・コード」も考慮に含めたいところ - オブジェクトの生成手順が手間という場合は、テスト用のオブジェクト構築Builderを定義したりすることも ### 疑問 > p.252 パブリックインターフェースのを証明する - この節の内容は「テストはassertionを書いて作る」「しかし、テスト対象が内部で依存を持ってる場合、対象自体がほんとに悪いかわからない問題になるよ」をいってるのだと思うけれど、このタイトルとどう繋がるんだろう。 :sore: :point_left: :+1: :+1: - ~~そもそも、「パブリックインターフェースを証明する」って、パブリックインターフェースの何を……?という~~ ↓の通り、一段落目で言及してた(^^; - 原文は *Proving the Public Interface* なので、訳の問題でも無い。~~残念!~~ - 一段落目で「テストは正しい値を返すことの証明」の話をしてタイトル回収は終わって、以降で余談をしてるだけ? :tashikani: - 余談 >> 表題 (^^; - 実際、第二段落以降は、「第一に求められることは、考えられ得るすべての状況にお いて正しい値を返すことを証明すること」と、直接関係ない話になってる……。 :desuyone: - 「考えられ得るすべての状況において〜」という話をするなら、 parameterized test とかの話に進んだほうが良さそうな気も > p.252: 受信メッセージは、その実行によって戻される値や状態を表明することでテストされます。 * テストと表明は同じものと見てよいのか? 目的が違うような。 :eyes: * テストは能動的に検査するのが目的 * 表明は受動的に異常が生じないようにガードするのが目的 :naruhodo: :+1: :+1: :+1: * assert を 表明 と訳すのに違和感...単純な英和としては良いのだけど。 :sore: * 目的の違いだけでなく、テスト目的で表明を書くということになり、表明が過剰な使われ方になり、本来の目的で書かれた表明がごみになりそう。 * ここでの「表明(assertion)」、プログラミング言語の機構やプログラミング手法としてのassertionではなくて、テストでassertって書いているのを以て「表明(assertion)」って言ってる? :kamo: * いやまあ確かにassertという語ではあるのだけれど、プログラミングの文脈で不用意に「表明(assertion)」って語を使われると↑で言われているようなそれと区別が一見してつかない(し、現状推測するしかなくなってる)ので、ちょっと脚注ぐらいは欲しかったなー感 - > Incoming messages are tested by making assertions about the value, or state, that their invocation returns - 「表明」はまんまassertionかー (・皿・ > p.253 Wheelの作成コスト - 作成コストとは何を指しているのだろう? :thinking_face: :eyes: - よくみたら、最初に2つの問題点を挙げるときは「1つはテストの実行時間です」と書いているのに、次の段落では「Wheelの作成コストが高い場合」となっていて、途中で実行時間→作成コストにすり替わっているのか :+1: :+1: - 内部的に依存が多いと作成コストが上がるという程度の話なんですかね。 - ↓の通り、また実行時間の話に戻っているので、主眼がどっちなのか(どっちもなのか)、謎…… :innocent: - 「作成コスト」と「実行時間」を同一視しているとか?~~ハハハ御冗談を~~ - 作成コストの高いオブジェクトを生成するコードは実行時間が長くなる、ということで、ここにおいては包含関係かと。 :+1: - ここで言う「作成コスト」が「作成自体に処理時間がかかる(e.g. テストデータを読み込んで〜)」を指すのだとその通りだと思いつつ、パラメータの種類や組み合わせが多くて「望むオブジェクトを作るためのコードを書くのが面倒」というケースも「作成コスト」にあたらないかな、と - 自分が最初に連想したのは後者のコストだったので、「よくわからん」ってなりました - あー、でもまあ、前後では「実行時間」ばっかり言及しているあたり、この本では「作成コスト」として後者をそもそも念頭に置いていない感じですかね。 :+1: - 「望むオブジェクトを作るためのコードを書くのが面倒」 最初これだと思いました。でも、「文脈的にこんなのでてこないよな?ん????」となった感じです。 :handshake: - そしてさらに次の段落では「テストは、最低限のコードを実行する場合に、最速で終わります」とあって、また実行時間の話に変わってる…… - 作成コストの原文: If Wheels are expensive to create, ... > pp.252-253の例 - https://discord.com/channels/432531367427964929/898843794101911622/1073962140618207262 - 実際この例でGearとWheelは分かれていた方が良いとは思うが、「内部が密結合しているオブジェクト = NG」的な書きぶりには違和感 :+1: :+1: :thinking_face: - 例えばオブジェクトの内部状態初期化とか、Javaの内部クラスで定義されるような内部状態を表現するオブジェクトとか、内部で完結しているべき & 密結合であるべき(独り歩きしてはいけないもの)というのはしばしば必要になる - そういうものまでやたらと疎結合にしてしまうと、たしかに「単体テスト」はできるけど、それと同時に「AとBはセットである」という情報も喪失するのでは?という疑問 - 実行コストを強調するのも、ちょっと危うい気がする。「じゃあ、実行コストが(今この瞬間は)軽微だから、別に密結合で良いよね」という主張に無力。 :+1: - 実際、この例におけるWheelの作成コストは微々たるものなので、実行コストの観点からは「分離せよ」という主張がかえって困難になっているのでは? - この次が「テスト対象のオブジェクトを隔離する」なので、今後の展開に乞うご期待。 ## {読書範囲} ### discord開始地点 ### 感想 ### 疑問 --- # ふりかえり - 感想/次回の課題それぞれで5分 - 要望に応じて :okawari: ## 感想 https://hackmd.io/E0HZBN9OS9GBAtnsYXjDsw#%E6%84%9F%E6%83%B3 ### 気づいたこと、気になったこと - 信じるものは掬われる(足元) - 節見出しすらも名が体をあらわしてなくて信じられない( - 一つ目のトピックは、タイトルが本文より本質を語ってるという、メソッド命名で考えたら理想的な形を体現していたかも。(二つ目は...) - 本題についてはその通りなのだが、一方で本題とは異なる話題がメインになっていたりして、命名はともかくメソッド設計という観点だと、あやしげ(^^; :ne: - タイトルにかこつけて、持論を展開するスタイル :scream_cat: :point_left: - もともとメソッド呼び出し≠メッセージングとは捉えていたが、今回の件で両者の違い(sender/receiverの関係性と、caller/calleeの関係性など)を~~本書へのツッコミを通じて~~言語化できたのは、副産物ながら収穫だった(^^; - 送信メッセージ・受信メッセージという翻訳の理解に脳みそ使いすぎた... :tsurai: :wakaru: - 本書の使い方からしてだいぶ混乱してるから、理解に苦しむのもしかたが無いところが大きい感…… :sob: ### 疑問点 ### 仕事に活用してみたいこと ## 次回の課題 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