give IT a try

プログラミング、リモートワーク、田舎暮らし、音楽、etc.

マトリョーシカ人形のようなメソッド設計を避ける

フィヨルドブートキャンプのコードレビューでよく指摘してるシリーズです。

次のようなパンを焼くRubyプログラムがあります。
このプログラムはどういう工程を経てパンが焼かれるのか、ぱっと把握できますか?

def main
  パンを焼く(粉, 水)
end

def パンを焼く(粉, 水)
  焼く(パンを発酵させる(粉, 水))
end

def パンを発酵させる(粉, 水)
  発酵させる(パンを整形する(粉, 水))
end

def パンを整形する(粉, 水)
  整形する(パンをこねる(粉, 水))
end

def パンをこねる(粉, 水)
  こねる(粉, 水)
end

main

上のプログラムは次のように書いても同じように処理されますが、工程の全体像がつかみやすいのはどちらでしょうか?

def main
  生地 = パンをこねる(粉, 水)
  整形された生地 = パンを整形する(生地)
  発酵した生地 = パンを発酵させる(整形された生地)
  パンを焼く(発酵した生地)
end

def パンをこねる(粉, 水)
  こねる(粉, 水)
end

def パンを整形する(生地)
  整形する(生地)
end

def パンを発酵させる(整形された生地)
  発酵させる(整形された生地)
end

def パンを焼く(発酵した生地)
  焼く(発酵した生地)
end

おそらく後者の方がぱっと全体像が理解しやすいと思います。
(こねる→整形する→発酵させる→焼く、という流れがmainメソッドを見ればわかるため)

前者と後者の違いは何か?

前者の場合、メソッド呼び出しと戻り値の関係を図式化すると以下のようになります。

実行すべき順序は「こねる→整形→発酵→焼く」ですが、メソッド呼び出しの順序は「焼く→発酵→整形→こねる」のように逆順になるため、処理の流れが直感的に理解しにくくなります。

また、コードの読み手は

「焼く、の前に発酵するの?」
「発酵、の前に整形するの?」
「整形、の前にこねるの?(で、どこまで続くの?)」

と、一番最初の処理に到達するまで手前のメソッドを確認し続けなければなりません。
これはまるで一番小さな人形に到達するまで、マトリョーシカ人形の蓋を開けていくような作業です。

Image: マトリョーシカ人形 - Wikipedia

一方、後者であれば以下のようになります。

一般的に、シーケンシャル(逐次的)な処理があり、前の処理の結果を利用して次の処理に進むような場合は、このように起点となるメソッド(この場合はmainメソッド)において、

  • 処理1を呼びだしてその戻り値1を受け取る
  • 処理2に戻り値1を渡して、その戻り値2を受け取る
  • 処理3に戻り値2を渡して・・・

と呼び出した方が、起点となるメソッドを見るだけで処理の全体像が把握しやすくなります。

前者のもう一つの問題点

前者のようなメソッド設計は「パンを焼く」メソッドが再利用しづらくなっています。
なぜなら、「パンを焼く」メソッドが受け取る引数は粉と水だからです。
つまり、常に処理のスタート地点からでないと呼び出せないメソッドになっています。
(この問題は「パンを焼く」以外のメソッドについても同様)

# 一番最後の工程のために、一番最初の工程で必要な引数を渡さなければならない
def パンを焼く(粉, 水)
  焼く(パンを発酵させる(粉, 水))
end

本来であれば、パンを焼くために必要なインプット(引数)は発酵した生地だけなので、以下のように発酵した生地を引数として受け取る方が再利用性が高くなります。

def パンを焼く(発酵した生地)
  焼く(発酵した生地)
end

たとえば、以下は冷凍して保存しておいた発酵生地を解凍し、それを「パンを焼く」メソッドに渡す例です。

解凍した生地 = 解凍する(冷凍された発酵生地)
パンを焼く(解凍した生地)

これであれば、「パンを焼く」メソッドがいろんなユースケースで再利用できますね。

参考:意図的にマトリョーシカにする場合もある

この記事では「マトリョーシカ人形のようなメソッド設計を避けよう」という話を書いていますが、意図的にマトリョーシカ人形っぽい設計を採用する場合もあります。

詳しくは触れませんが、Rack(もしくはPythonのWSGI)のアーキテクチャはマトリョーシカ人形的です(タマネギによくたとえられます)。

Image: "RBS generation framework using Rack architecture"の予習記事 - READYFOR Tech Blog

デザインパターンのDecoratorパターンもマトリョーシカっぽい設計になることがあります。
参考 JavaでDecoratorパターン - Qiita

ただし、どちらもケースもインターフェースを完全に揃えているのがポイントです。
すなわち、内側の処理も外側の処理も「同じメソッド名・同じ型の引数・同じ型の戻り値」になっており、各処理を自由に差し替えられる利点を持っています。

このへんの話を詳しく説明し始めると長くなるのでここでは割愛します(気になる人は調べてみましょう!)。
とりあえず、上級テクニックではあるものの、きちんとルールを決めて使えば「マトリョーシカ人形」も有効に働くケースがある、ということだけ覚えておいてください。

おまけ:Elixirのパイプライン演算子を使うとこうなる

マトリョーシカではないRubyコードはこんなふうに書きましたが、

def main
  生地 = パンをこねる(粉, 水)
  整形された生地 = パンを整形する(生地)
  発酵した生地 = パンを発酵させる(整形された生地)
  パンを焼く(発酵した生地)
end

Elixirのパイプライン演算子を使うと、上と同じ処理がこんなふうに書けます。

def main do
  パンをこねる(粉, 水)
  |> パンを整形する
  |> パンを発酵させる
  |> パンを焼く
end

こういう処理だとElixir(というか関数型言語?)の方がよりシンプルで美しく書けますね。

【PR】フィヨルドブートキャンプでメンターやってます

僕はフィヨルドブートキャンプというプログラミングスクールでメンターをやっています。
完全未経験の人でもプログラミングを学べるので、興味がある人はぜひ覗いてみてください〜。

bootcamp.fjord.jp

ガスで焼くたこ焼きがホットプレートで焼くたこ焼きの5倍美味しかった

最近、たこ焼き系YouTuberなる人がいるらしく、その人が「たこ焼きを焼くなら絶対コレ!!」とオススメしていたたこ焼き器を買いました。
イワタニの炎たこ 2(えんたこツー)というカセットガスで焼くたこ焼き器です。

今まではホットプレート用の「たこ焼きプレート」を使って焼いていたのですが、ガスで焼くたこ焼き器で焼いたら、たしかにめっちゃ味が変わりました!!

なんか外がカリッと香ばしく焼けます。中ももちっと、ふわっと、とろっと焼けます。

特に外の香ばしさは、ピザのこんがり焼けたクラストに近いイメージです。

Buffalo Chicken Pizza

ホットプレートで焼いたたこ焼きは冷めるとふにゃっとして美味しくなくなりますが、ガスで焼くと冷めてもなんか美味しい!

あと、火力が強いのでホットプレートよりも早く焼けるところもgoodです。

食べる前は「そんなに変わるんか〜?」と半信半疑でしたが、実際に食べてみると「うおお、これは確かに違う!!」となりました。
みなさんも騙されたと思ってぜひ買ってみてください!

P.S.
食べるのに夢中で、たこ焼きのできあがり写真を撮るのを忘れてしまいました。どうもすいません……。

もしもTwitterが終了したら

はじめに

なんか最近「Twitterが終了するかも」みたいな話題が急に持ち上がってきましたね。
Twitterがなくなったら困るし、寂しいな、とは思うけど、一企業が運営するSNSなので未来永劫続いていく保証はありません。
とはいえ、ここ数ヶ月(数週間?)の動きは急転直下すぎていったいどうなんだとは思いますが。

本当にTwitterがなくなるのか、それとも形はどうであれ続いていくのかはタイムマシンがないとわかりませんが、「もしTwitterがなくなったらどうしようかな」というのをちょっと考えてみました。

Twitterがなくなったらブログに逆戻りするかも

そうですね、Twitterがなくなったら、またブログメインに戻ろうかと思います。

実はこのブログ、僕がTwitterを始めるのより前にスタートしてるんですよね。
ブログ開設が2009年で、Twitterを始めたのが2010年です。

Twitterを始めるまではブログ上で短い小ネタ、つまりツイート的なものを書いたりしていました。
Twitterは「ミニブログ」と呼ばれたりすることもあるので、一種のブログと見なすこともできます。
そのミニブログがなくなったら大ブログ、つまりこのブログに戻ってきたらいいか、という考えです。

Please follow me!

というわけでTwitterを僕をフォローしてるみなさんは、Twitterが終わる日に備えて(?)このブログの読者になってほしいです!
「読者になる」ボタンをクリックしてもらったら、僕がブログを更新したときにメールで通知が飛ぶようになります。


RSSリーダーで購読するのもアリ

ただし、このブログは「はてなブログ」を使っているので、読者になるタイミングではてなのアカウントも作成する必要があります。

ブログは購読したいけど、はてなのアカウントは作りたくない、という人はFeedlyのようなRSSリーダーを使うといいかもしれません。

feedly.com

RSSリーダーを使えば、僕のブログが更新されたタイミングでフィード上に最新の記事が上がってくるようになります。

ブログを購読するにはこんな感じで僕のブログURL(https://blog.jnito.com/)を登録すればOKです。

もちろん、RSSリーダーを使えば僕以外のブログ記事も同じように購読できます(僕も日常的にRSSリーダーでいろんな人のブログをチェックしています)。

おまけ:Qiitaにもフォロー機能があります

Twitter終了とは直接関係はありませんが、Qiitaにもフォロー機能があるので、僕の書いた技術記事をチェックしたい人はQiitaアカウントのフォローもよろしくお願いします!

qiita.com

ネット上で知り合ったみなさんとの交流をどうするか?

単なる情報発信(アウトプット)だけに絞れば「Twitterの代わりにブログを書く」、で代用できそうですが、Twitterってアウトプットだけじゃなくて、交流ツールとしての側面もあるんですよね。

Twitter上ではリアルではほとんどお会いしてないITエンジニアの方々とリプライ欄等でやりとりすることがあります。

もちろんこのブログにもコメント欄はあるんですが、なんかブログのコメント欄ってTwitterのリプライに比べるとちょっと敷居が高いですよね。気軽に書き込みづらいというか。
特に、僕のブログはスパム防止策としてコメントを承認制にしているので、Twitterのようなリアルタイム性がさらに希薄になっています。

こうなってくるとTwitterに変わるSNSが必要になってきそうです。
何がTwitterの代用になりますかね〜?

Instagram?毎回写真載せないといけないしなあ。

Facebook?僕、Facebookは基本的にエンジニア色を出さない形で使ってるんですよねえ。

TikTok?アカウント持ってないし、Twitterの代わりになるとは思えない。

SlackやDiscord?これはなんかクローズドなチャットツール、っていう印象です。パブリックにやりとりするイメージがあまりないなー。

Mastodon?もしかするとこれが最有力候補かもしれませんね。もともとTwitter的な使い方をするツールだし。そのうちどこかのサーバーが技術者向けとして賑わったりするのかなー?ただ、僕はまだ使ったことがないです、Mastodon。

という話を書いていたらなんとなく日本のITエンジニアはMastodonに流れていきそうな気がしたので、しばらく動向をチェックしておこうと思います。

Twitter DMをどうするか?

Twitterはたまに「初めまして」の人からDMをもらうこともあります。
DMの代わりは何がいいんでしょうねえ。
メールアドレスの公開?でもスパムがいっぱい来そうでイヤなんですよねえ。

いちおう、僕個人のFacebookページがあって、ここからFBメッセージが送れるようになってます。
Twitter DMの代わりに何か僕個人に向けたメッセージを送りたい場合はこれを使うといいかもしれません(今でもたまにここから連絡をもらうこともあります)。

Junichi Ito's Books(伊藤淳一の著書)| Facebook

もし僕がMastodonを本格的に使うようになったら、MastodonのDM機能を使ってもらうのもいいかもしれませんね。

まとめ

というわけで、このエントリでは「もしもTwitterが終了したら」というお題で、なさそうでありそうな、ありそうでなさそうな「もしも」を考えてみました。

いやはや、どうなるやら、Twitterさん。
いいところも悪いところもありますが、Twitterはやっぱり便利なツール、というか、ある種の社会インフラに近いツールなので、個人的にはなんとか続いていってほしいと願っています。

P.S.

コロナが流行しだした2020年以降、何かにつけて「まさかこんなことが現実に起きるとは思わなかった」と思うようなことがたくさん起きている気がします。
いいことならまだしも、「できたら起きてほしくなかった」と思うことの方が次から次に起きているような……(具体例を言い始めると気が重くなるのでここでは挙げませんが)。

ちょっと前までぼんやり思ってた「個別に見ればいいこと、悪いこと、いろいろあるけど、総じて見れば人類には平和で明るい未来が待っているはず」という感覚が戻ってきてほしいなあと思う今日この頃です。