fukabori.fm 48, 49回が神回だった

私の情報収集源のひとつにpod castがある。

もともと移動中に聞くのが定番だったが、在宅勤務になって以降はもっぱらジムでストレッチや筋トレをしながら聞いている。 ちょっと前のfukabori.fmのtwadaさんゲスト回でGoFデザインパターンとDIコンテナの話をされていて、学びが非常に多かったのでメモついでにアウトプットしておきたいと思う。

上記の2回に渡るエピソード、今までもやーっとしていたところが急にクリアになった感じがしてすごく嬉しかった。

継承とポリモーフィズムのモヤモヤについて

前提として、まだ私はGoFデザインパターンをすべて理解できていない。 結城さんの有名な本を少し読んでみたけど、使い所にいまいちピンと来ていない感じ。

サンプルコードを写経するだけでは使い所の感覚がどうにも得られない。 頭の中で言葉としては理解できた原理原則と利用シーンとが結びつかないのだろう。そういうレベル感。

単純に理解力の問題だけかもしれないが、実際にコード書いてみて壁にぶち当たったりしたときに改めてサンプルコードを眺めると、「あっ!」と思えるのかな、なんてのんきに構えていた。

とくにポリモーフィズムがよくわからない。 継承まではわかるのに、ポリモーフィズムになると、なんだか急に輪郭がボケてしまう。

以上が前置き。で、この辺の話がFukabori.fmエピソード49の「Don’t Repeat Yourself 原則と差分プログラミング」という項目で一気に晴れた。 輪郭がボケてモヤモヤしてたところって自分でもイマイチ言語化できてなくて「何がわからないかわからない」状態だったと思う。 以下、継承と差分プログラミングとDRY原則の話の流れの中で、そのままではないけどこんな感じの会話があり、これが的確すぎて目からウロコが落ちまくった箇所。

iwashiさん 「プログラミングを勉強している人にとっては継承とDRYがごっちゃになると思うんですけどどうですか?(DRY=継承となりがちでは?という意味)」

twadaさん 「DRY原則を求めていこうとすると継承を使って差分プログラミングをしたくなってくるんですよね」

私 「うぉぉーっ!そうなんですよぉー!!」(100回うなずく)

iwashiさんの質問とそれについてのtwadaさんの回答のひと言目がまさに、私が今まで言語化してなかったけど考えていたことだった。 で、この前後のtwadaさんの解説がわかりやすくて一気に目の前がひらけていく。継承で起きる問題がやっと実感できたので、そこで初めてポリモーフィズムの概念が飛び込んできたって感じ。

  • 継承は親クラスと子クラスの間に強い結合をつくってしまう。
  • 継承と差分プログラミングを使っていろんなバリエーションに対応しようとすると大変である。
    • 少しずつ違う箇所をオーバーライドした子クラスを大量に作ることになりがち。
    • 差分に対応しようとして親クラスの実装を変えると、他の子クラスに影響が出てしまうことがある(密結合)。
  • 色んな所で実装がオーバーライドされると、どこでなにが行われているかわからない。これは実質スパゲッティコードである。
  • オブジェクト指向におけるコードの再利用とは、差分プログラミングによる実装の再利用ではなく、ポリモーフィズムを使うことによる利用側のコードの再利用である。

デザインパターンを学ぶといいところは、DRY原則を求めるために継承を使って実装を親クラスにまとめる、というアプローチ以外の手法を知れること、という話はとても腹落ちした。 ここまでの一連の、継承の課題感〜ポリモーフィズムの意義というのがあって初めて、「インターフェースに対してプログラミングする」という概念の輪郭を見ることができた。

これがコードで実装できるようにもう一度デザインパターンの本を読んでサンプルコード書いてみて、実際の動いているコードでも探してみると良いのだろうな。

リファクタリングのターゲットとしてのデザインパターン

後半のリファクタリングの話とからめてのデザインパターンの話もめちゃくちゃ納得感があって、すごく良かった。(語彙力) GoFデザインパターンは現代においては当初の役割や考え方から変わってきているという話。

システムは最初にちゃんと設計しましょうという思想のもと、変更に強いコードにするための手法として紹介されたデザインパターンであったが、リファクタリングと自動テストがデザインパターンのあとに出てきて以降は設計はあとから変更できるものになった。 これによって設計に対する思想は大きく変わって、設計のベストプラクティスとしての位置づけのデザインパターンから、リファクタリングのゴールとかターゲットとしてのデザインパターンに変わっていったとのこと。

リファクタリングをしながらデザインパターンに近づけていく。GoFのデザインパターンはリファクタリングの結果生まれてくるもの。

Martin Fowler のリファクタリングの本を以前社内の読書会で読んでたのだけど、実はいまいち利用シーンというか何が嬉しいんだっけ?みたいなのがしっくりこなかったり、やってる内容が追っかけられなかったりしていた。

デザインパターンとリファクタリングを行ったり来たりしてみると解像度がかなりあがりそう。 結城さんのデザインパターン本、「デザインパターンはリファクタリングのターゲット」という前提をもって改めて読みすすめることにしよう。

DI・DIコンテナについて

これが主題だったのでエピソードの流れとしては前後するが触れておく。

これも私の中でいまいち理解できていない概念の筆頭。雰囲気で読んで字面で理解しているので自分で実装するときには使えないやつだと思う。 シングルトンの話から派生してDIの話に移っていったこともあり、背景にある解決したい課題が非常にくっきりとした状態で、DIの良さやDIでなにをどのように解決するのか、という話が聞けて学びが多かった。

継承のときもそうだけど、課題をしっかり認識しないとその解決策や打開策の概念って入ってこないんだなと実感。 こんなに順を追ってわかりやすく解説できるものなんだな、という謎の感動を得た。 iwashiさんが丁寧にそれぞれの単語を拾ってくれるのもありがたい。

分かっている人にとってはDIの良さって共通認識があるだろうし、私も本とかネットとか見て説明読んだりしたことがないわけじゃない。だけどなんか引っかかったままのモヤッとしたポイントがあって、そこがクリアにならないために全体像を掴みきれてない不安感みたいなのが残っている状態。 これについてもポリモーフィズムと同じで、モヤがかかってたところにスポットライトがあたって、輪郭が浮かび上がってモヤが晴れていく感じだった。

シングルトンはいわゆるグローバル変数的な存在(有名人)になってしまいがち。色んな所に引っ張り出されると、呼び出し方を知っておかなくちゃいけないし、どこでどのように呼ばれているか制御できなくて辛いよね、という話。 コンストラクタインジェクションでインスタンスをnewしたときにシングルトン(有名人)を呼び出すのではなく、インスタンスをnewしたら自動的にそこに必要な人がすでにそこにいる(依存性が注入されている)状態が理想。

DIコンテナの実装例の話は、かなり単純にして説明してくださっていたようでわかりやすかった。 以下ざっくりまとめ。

  • 依存関係をコンテナの中に閉じ込めてしまってDIコンテナが汚れ役になる
  • DIコンテナの存在を知っているのはmain関数のみ、というような状態にする。
  • 呼び出し側はふるまい=インターフェースを使うだけで良くなる。
  • インターフェースを提供する側は変更に強く保守性の高い実装すれば良いという形で責務を分けることができる。

まとめ

2回に渡る配信を通して、振る舞いに対してプログラミングする、インターフェースに対してプログラミングする、というなんかふわふわしてた概念が急に目の前に輪郭をもってあらわれた衝撃をうけた。 知識ベースではあるけど、ひさびさに手応えのあるパラダイムシフトが起きた感じがした。

2エピソードで2hちょっとだったけど、すごく良かった。移動中に1回聞くだけではもったいなくて、家でもう1回聞き直して走り書きのメモをもとにこうして書き出してみた。 全てに対して完全理解ではないけど手がかりがたくさん増えた手応えがとても嬉しい。

これがプログラミングの面白いところなんだよなぁ、とにやにやしてしまう。 たまたま見たこの記事にも同じようなことが。勇気もらえる。

https://cult.honeypot.io/reads/anyone-can-be-a-software-engineer/

Many of us struggle finding our way through tough bugs. We sometimes battle learning a new subject or technology that isn’t making sense. It can be frustrating.

Like wanting to throw your computer out of the window frustrating.

But once solved, whether it’s a few hours or a few days later, the rush of dopamine from the accomplishment is unmatched.

This same feeling happened many times while learning how to program. Some would say learning to do so is impossible for them - I’d disagree! Persistence and grit is key, which is in your control :).

The key is continuously learning and staying positive throughout! Trust me, it’s worth it.

コード書きながら「進研ゼミだ!」ができそうな日が近そうで、楽しみ。