ナカザンドットネット

それって私の感想ですよね

トキブルワリーはいいぞ

Beer Advent Calendar 2023 - Adventarの3日目です。今回はトキブルワリーさんについて紹介します。

トキブルワリー

トキブルワリーは佐渡ヶ島のマイクロブルワリーです。

t0ki.beer

元フラー社CTOの藤原さん(@wutali)がやっており、新潟でソフトウェアエンジニアをやっている筆者としては、かなり身近に感じられるブルワリーです。

名前が独特

ソフトウェアエンジニアが作っているビールということで、名前も独特です。

今年のゴールデンウィークに、新潟明訓高校*1の隣にある亀田公園で行われていたバルイベントで飲んだのは、「BOOT」という名前でした。

BOOT v2.0-b.YQH-1320

t0ki.beer

また、11月には新潟駅南口近くのアマリロさんで、「SSL」というビールを飲む機会もありました。

SSL v1.0

t0ki.beer

暗号化されていない爽やかなお味でした。

どうやらP2B Hausさんで色々と飲める機会もあったようです。

ソフトウェアエンジニアなら、思わずクスリとしてしまうような名前のビールばかりです。

もちろん味も試行錯誤が繰り返されていて、美味しいものばかりですよ!

見かけた際はぜひ飲んでみてください。

*1:ドカベンのあそこです

3分投資診断の思い出

モニクルAdvent Calendar 2023の2日目です。昨日はCTOのがぶちゃんによる「エンジニア10人を超えて複数チームになった開発組織でCTOとして最近やっていること」でした。

gabu.hatenablog.com

2日目の今日は、筆者(@Nkzn)が入社直後に開発に携わった「3分投資診断」というサービスの思い出話をします。

3分投資診断とは

3分投資診断は、モニクルグループのワンマイルパートナーズが運営している、はたらく世代のお金の診断・相談サービス「マネイロ」が提供するサービスのひとつ*1です。

moneiro.jp

年齢や年収、現在の資産形成の概要、老後の過ごし方などを入力していくと、老後までにあとどのくらい資産形成が必要で、そのためにはどういった施策が有効そうなのかを、ざっくり診断してくれます。

3分投資診断の診断結果の例

思ったより反響があった

オウンドメディアのモニクルプラスでも話したことがあったのですが、思った以上の反響がありました。

plus.monicle.co.jp

実は、筆者は計算エンジンの部分を2021年の秋ごろに実装し終えたあたりで開発から離脱しており、その後にこだわりのUI開発戦記があった時期については別のプロジェクトをやっていました。運用周りも当時のグロース関連のチームに任せてしまったので、あまり数字を追いかけることもしていませんでした。

そんな筆者が驚くことになるのは、ちょうど一年前、昨年の12月に上記のインタビューを受けたときです。創業者の泉田さんから「3分投資診断すげーことになってるよ!めっちゃ使われてる!」と教えてもらって、そんなことになってんの!?と驚いた記憶があります。

診断結果を受けてもっと詳しい対策を知りたくなったお客さんが、診断後にマネイロの相談サービスを申し込んでくれるケースも診断数に応じて増えているらしく、マネイロの2022年の成長を強力に後押ししたとのことでした。

筆者からすると、入社から半年も経たないうちに作っていたものということもあり、がむしゃらに取り組んだいくつかの施策のうちのひとつ、くらいの感覚でした。入社から1年半経った頃に、1年越しに大ヒットを知らされて、やってきたことは無駄じゃなかったんだなあ、としみじみしたものでした。

ドメインエキスパートとの共同開発で気をつけたこと

あまり表舞台で開発の話をしたことがなかったので、少しだけ開発の思い出話もしようと思います。

基本的には役員の皆さんがドメインエキスパートとして仕様をまとめてくれていました。大量のスプレッドシートに根拠資料や計算式が並んでいるイメージです。

筆者は計算エンジンの作成担当だったので、簡単なUIだけを用意して、基本的には数字のインプットとアウトプットが正しそうかどうかをドメインエキスパートと擦り合わせていく作業を行っていました。

ここで特に意識したのが「正しさの確認しやすさ」です。プログラマーではないドメインエキスパートから「○○の項目のアウトプットが怪しい気がするんだけど、動作確認してる時はどんな数字が出てた?」と聞かれたときに、ソースコードを見せながら議論するわけにもいきません*2。次善策として、できるだけテストコードの処理結果で各種の途中計算の結果が見えるようにしてみました。例えば、年金の算出のために必要な「厚生年金対象勤務期間」や「標準報酬月額」の算出の自動テストでは、次のような実行結果が表示されます。

PASS  hoge/services/index.test.ts
  「厚生年金対象勤務期間」の算出
    ✓ 退職年齢65歳、勤務開始年齢24歳、未加入期間5年の場合、厚生年金対象勤務期間は432ヶ月である (1 ms)
    ✓ 退職年齢75歳、勤務開始年齢23歳、未加入期間10年の場合、厚生年金対象勤務期間は504ヶ月である
  「標準報酬月額」の算出(令和3年3月データによる検証)
    ✓ 年収が0万円のとき、標準報酬月額は88000円である
    ✓ 年収が468万円のとき、標準報酬月額は380000円である
    ✓ 年収が720万円のとき、標準報酬月額は590000円である
    ✓ 年収が1000万円のとき、標準報酬月額は650000円である
    ✓ 標準報酬月額表を検索できる(表はテストデータで代用) (2 ms)

これなら、ドメインエキスパートに見せたり、検算してもらったりするのも、ある程度は容易です。最終的に数百件のテストケースを作成しましたが、ほぼすべてのテストケースをこのノリで作り、順次ドメインエキスパートに確認してもらいながら開発を進めていきました。

こういったテストの作成においては、JUnitで学んできた*3Parameterized Testの考え方が役立ちました。今回はテスティングフレームワークとしてJestを採用していましたが、 test.each() を用いると、次のように簡単にParameterized Testが書けるので、重宝しています。

describe("「標準報酬月額」の算出(令和3年3月データによる検証)", () => {
  test.each([
    [0, 88_000],
    [468, 380_000],
    [720, 590_000],
    [1000, 650_000],
  ])(
    "年収が%i万円のとき、標準報酬月額は%i円である",
    (yearlyIncome, standardMonthlySalary) => {
      const actual = calcStandardMonthlySalaryYen(yearlyIncome)
      expect(actual).toBe(standardMonthlySalary)
    }
  )
  test("標準報酬月額表を検索できる(表はテストデータで代用)", () => { ... })
})

「読みやすいテストケース」というのは、かなり認知負荷を下げるのがわかったので、無理に慣れない英語でテストケースの名前を書いて、書いた人も読んだ人もパッと意味がわからないものになるくらいなら、躊躇わずに日本語で書いていくのがよいと思います。

宣伝:マネイロの広告を探せ!

12月1日から、東京メトロにマネイロの広告を掲出しています。

答えはマネイロの3分投資診断で!(ワンマイルパートナーズUさん撮影)

新潟からフルリモートで働いている筆者はなかなか見る機会がないので、もし見つけた人は #マネイロ のハッシュタグと共に @Nkzn まで「見つけたよ!」のリプをいただけると、めちゃくちゃ喜びます。

中旬には筆者もモニクルグループの全社納会へ参加するために東京へ行く予定なので、そのときに探してみようと思っています。

明日は新潟メンバー仲間の@circled9です。よろしく!

*1:他にも、オンラインセミナーや相談サービスなどもあります

*2:ドメイン駆動設計の本来の精神に則るならば、ドメインエキスパートが読めるようなプロダクトコードを書くべきではありますが、あれは英語が母語な人たちだからこそ成り立ってる部分もあると思うので、今回は勘弁してください。日本語でコードを書けばたぶんできるんだけど、そこまではやってられない。

*3:そろそろ自分でも忘れかけていますが、Android Java出身エンジニアなんですよ僕

至高を越えたボロネーゼは自分へのご褒美として作る最高のご馳走

12月といえばアドベントカレンダーの季節! そして、昨年に引き続き、やります! バズレシピアドベントカレンダー!

adventar.org

言い出しっぺということで、1日目をやらせていただきます。

今年も色々と作ってきて、子供ウケが良かったレシピも時短に効いたレシピも色々とあったのですが、今回は「筆者個人が自分で食ってて一番美味かったやつ」というシンプルかつ最も重要なところを紹介します。

至高を越えたボロネーゼ

筆者の中で、バズレシピオブザイヤー2023はこいつでした。 「至高を越えたボロネーゼ」 です。

www.youtube.com

今年のパスタレシピは、冷製パスタ焼きスパゲティのような例外を除いて、ほぼ全レシピがワンパンパスタだったと思います。昔のパスタレシピをリゾッタータ(ソースでパスタを茹でて煮詰める手法)で再構築しつつ進化させることでネタ切れを防いでいた側面があったような気もします*1

そんな中で、筆者が今年本当に食べていて幸せだったのが、この至高を越えたボロネーゼです。

至高を越えたボロネーゼ

2020年に出ていた至高のボロネーゼのワンパンバージョンとなります。材料としてもそんなに変わらないはずなのですが、至高の〜よりも圧倒的に好みです。別茹でせずに煮詰めて作っているからか、ソースが麺にめちゃくちゃ絡むんですよねえ。動画ではコラボ相手として使っていた赤ワイン「ジェイコブズ・クリーク」は近所に売っていないので、適当な赤ワインを買ってきて作っていますが、全然美味しいです。一緒に飲むとマリアーーーーージュ🍷になります。

動画の出始めのときには週3で食べてましたが、今は「ここぞというときの自分へのご褒美」として作るようになりました。ちなみに↑の写真は、11/12の技術書典15オフラインイベントと、11月16日の4年半ぶりの新刊脱稿を乗り越えた自分へのご褒美として作ったやつでした。

デメリットはパスタとして食うしかないこと

このレシピは、たぶん来年以降もプチハレの日のレシピとして鬼リピすることになるのですが、一点、ただ一点だけ、旧作である「至高のボロネーゼ」のほうが優れていると筆者が思っている点があります。

至高のボロネーゼは、ソースだけを別の料理に転用可能なのです。白米に乗せて、ボロネーゼ丼を作ってみてください。旨すぎてトビますよ。

至高を越えたボロネーゼは、良くも悪くも煮詰めることでパスタとソースが一体化し、ソースだけの状態が存在しないレシピです。そのため、ボロネーゼ丼を作る余地がほとんどありません。ごく稀に、食べるのが下手くそすぎて麺に具を絡めきれずに、食べ終わった皿にソースがそこそこ残っているという事態はありますが、これは直後にシメとしてボロネーゼ丼を食べるようなことはできても、冷蔵庫に保存しておいて後日リメイクしましょう、という話にはならないですよね。

というわけで、パスタ以外にもボロネーゼの楽しみ方を模索したい場合は、至高を越えたボロネーゼは向いていません。至高のボロネーゼや、シン・ボロネーゼのほうが向いています。

ワンパンパスタ最高!

ワンパンパスタシリーズは、やっぱり洗い物が少ないという最高の利点があるんですよね。まな板と包丁とフライパン(+α)あたりがあれば大体作れてしまうので、時間があまりない昼食にも重宝しました。

リュウジさんがいつまでワンパンパスタを擦り続けるつもりなのかは分かりませんが、2024年も楽しみですね!

2日目を書いてくれる人を募集中です

ところで、このアドベントカレンダー、2日目に誰が書くのか決まってないんだけど、どうしようかなあ。誰も書かなかったら僕が最高傑作カルボナーラの話をしますが、欲を言えば誰か書いて欲しいなあ。12/2は会社のアドベントカレンダーの担当なので、他に書きたくないんじゃよ。誰か頼む……

*1:これの別茹で版を作ったことある気がする、みたいなレシピが多かった

書評:これからはじめるReact実践入門

明日、2023/9/28に発売する「これからはじめるReact実践入門」を献本いただきましたので、簡単に目を通した感想を書こうと思います。

これからはじめるReact実践入門

目次

かなり網羅性が高い

パラパラと読んでみて感じたのは、かなり手広く、それでいて一定の深みもある本だということです。出版社のサイトにある目次を見てみましょう。

Chapter 1 イントロダクション
1-1 ReactとJavaScript
1-2 Reactアプリを開発/実行するための基本環境
1-3 モダンJavaScriptの基本

Chapter 2 Reactの基本
2-1 はじめてのReact
2-2 サンプルアプリの内容を確認する
2-3 JSXの基本

Chapter 3 コンポーネント開発(基本)
3-1 コンポーネントを支える基本概念 – PropsとState
3-2 条件分岐と繰り返し処理
3-3 Props/Stateの理解を深める
3-4 より高度なイベント処理

Chapter 4 コンポーネント開発(フォーム)
4-1 フォーム操作の基本
4-2 Stateにおける構造化データの更新
4-3 検証機能の実装 – React Hook Form

Chapter 5 コンポーネント開発(応用)
5-1 組み込みコンポーネント
5-2 コンポーネント開発でのスタイル定義
5-3 コンポーネントのその他の話題

Chapter 6 Reactライブラリの活用
6-1 典型的なUIを実装する – MUI
6-2 コンポーネントの見た目/動作をカタログ表示する – Storybook
6-3 外部サービスからデータを取得する – React Query

Chapter 7 フックの活用
7-1 コンポーネント描画/破棄時に処理を実行する – 副作用フック
7-2 さまざまな値への参照を準備する – useRef関数
7-3 状態と処理とをまとめて管理する – useReducer関数
7-4 コンポーネントの複数階層で値を受け渡しする – useContext関数
7-5 ステート管理ライブラリ「Recoil」
7-6 関数、またはその結果をメモ化する – memo/useMemo/useCallback関数
7-7 優先順位の低いState更新を区別する – useTransition関数
7-8 フックの自作

Chapter 8 ルーティング
8-1 React Routerの基本
8-2 ルーター対応リンクの設置
8-3 ルーター経由で情報を受け渡しする手法
8-4 Routeコンポーネントの属性
8-5 ルーティングに関わるその他のテクニック

Chapter 9 テスト
9-1 単体テスト
9-2 E2Eテスト

Chapter 10 TypeScriptの活用
10-1 TypeScriptの基本
10-2 ReactアプリへのTypeScriptの導入

Chapter 11 Next.jsの活用
11-1 Next.jsの基本
11-2 App Routerの基本を理解する
11-3 応用アプリ「Reading Recorder」を作成する
11-4 アプリの実装を読み解く
11-5 Vercelへのデプロイ

668ページの本なので、そこそこ長いです。

全体の構成としては、次のようにまとめられるでしょうか。

  • Chap 1〜3:基本理念の解説や、言語の文法やReactの基礎文法について解説
  • Chap 4〜5:React単独でできること
  • Chap 6:ライブラリを組み合わせると、更にできることが広がる
  • Chap 7:組み込みフックの解説と、フックを活用したライブラリの紹介、そして自作によって、関数コンポーネントをより柔軟にシンプルに扱う
  • Chap 8:シングルページアプリケーションを成立させるための画面遷移
  • Chap 9:品質保証
  • Chap 10:Reactで一通り何ができるのかわかったところで、型の支援を受けて実用レベルの使い方を知る
  • Chap 11:ここまで読めば、ある程度大きい概念も理解できるようになってきているはずなので、デファクトスタンダードなフレームワークであるNext.jsを学ぶ

私もReactの学習については頭を悩ませたことがあるのですが、大筋としては良い流れで書いてあると思います。TypeScriptは現代の開発では事実上必須ではありますが、慣れていないうちにReactやReact関連ライブラリの解説をTypeScriptで行なってしまうと、今学んでいるものがReactなのかTypeScriptなのか、読者は混乱してしまうでしょう。思い切ってTypeScriptの解説を終盤の応用編として収録したのは、英断だったと思います。著者の山田さんと私は編集者と著者という関係で記事を一緒に作ることが多いのですが、やはりTypeScriptの登場タイミングの匙加減について話し合うと、お互いに「悩ましいけど、本気でライブラリの解説にフォーカスしたいなら、最後にちらっと解説するか、いっそTypeScriptに触れないか、ですよねえ」という結論になりがちなので、「最後にちらっと解説」の一例として、納得感のある構成になっていると思います。

また、膨大なページ数を使っているだけあって、一つ一つの項目がかなり丁寧です。よそのプログラミング入門書には、初心者向けだからと詳細な説明を省いている残念な本も多いのですが、この本では細かい点まで親切に解説されています。おそらく、React歴3年目くらいまでの人が読んでも、初めて見る基礎的な知識が多く記載されていることでしょう。

多くのページが実際に手を動かして、手元で動作を確認しながら読み進められるものになっています。そして、そのとき何が起きているのか、どんな仕組みで動いているのか、といった背景にも存分に触れているので、楽しみながら読み進められると思います。

足りない情報があったら

この本は「広く・やや深く」という感じで進行していくので、物足りなさを感じる場面というのは少ないのですが、もっと深く知りたいな、と思った場合には、専門の書籍をあたると良いと思います。

P264のコラムでは参考書籍が紹介されていますが、直接的な深掘りができるタイプの本が紹介されていないのが気がかりなので、この場を借りて、少し紹介しておきます。

プロを目指す人のためのTypeScript入門

まずは、相対的にちょっと浅めになっている、TypeScriptを深掘りしたい場合の本ですが、これは@uhyoさんのブルーベリー本で良いでしょう。

gihyo.jp

Next.jsについて、次に読む本はありますか?

ぶっちゃけこれはかなり難しいです。現行のNext.jsの本は、大半がPages Routerを前提にしており、App Routerの使い方を書籍として取り上げた本がまだほとんどないはずです。商業出版の紙の本としては、本書が日本最速では……?くらいのレベルです。

とはいえ、本書に記載されたNext.js(のApp Router)の使い方は、「よくできたチュートリアル」くらいのものなので、もっと深い情報も欲しいですよね。

2023年9月現在では、「公式ドキュメントを読んでくれ……!」が一番誠実な回答かなという感じはしています。

nextjs.org

一応、私も↓でApp Routerの連載を行っていますが、少しずつしか進んでいないので、たまに読んでいただければ、くらいのものです。

codezine.jp

App Router前提で、広く深くNext.jsについて扱った書籍が今後出てくることを期待したいですね〜。

補足したいところ

全体的にはよくできているのですが、細かいところで気になったところがあるので、補足情報を書いておきます。嘘が書いてあるわけではないので、本書の内容そのままに読み進めていただいても問題ありませんが、2周目を読み始めたあたりで気にしてみると面白いかもしれません。

Create React Appを使わない選択肢もある

本書の中で、Next.jsの話題が登場するまで、一貫してReact製アプリケーションの環境構築&ビルドツールとして解説されているCreate React Appですが、現代では役割を終えたものとして、開発がほぼストップしました。最新のReact公式ドキュメントでも、プロジェクトのセットアップに使うツールにCreate React Appは登場しません。

react.dev

業務レベルのプロジェクトを作成するのであれば、Next.jsやRemixといったフレームワークを利用したほうが、より高度に通信と画面遷移が統合された、快適な開発体験を得ることができます。ただし、Create React Appと比べると、プロジェクトの最低限のファイル数は多くなりますし、一定の複雑さがあることは否めません。

入門書での取り回しがいいのは、確実にCreate React Appなので、本書の選択は正解だと思います。ただ、本当に業務で実践できる内容に持っていこうと思った場合は、やはり本書の最後の章で解説されているNext.jsを導入したほうがよいでしょう。

ちなみに、公式ドキュメントではほんの微かな言及しかありませんが、Create React Appと近い規模感&使用感でプロジェクトを扱えるツールとして、Vite(ヴィート)があります。

ja.vitejs.dev

ほんの少しクセの強さはあるものの、こちらは活発に開発が続いていますし、一定の人気もありますので、場合によっては本書のサンプルをViteで作成・動作させてみても面白いかもしれません。

Recoilさんは開発状況がちょっと心配

Recoilは人気はあったものの、リポジトリ名がfacebookexperimental/Recoilだったことからも分かるとおり、Meta社内でも実験的なプロジェクトでした。社内ライブラリをちらっとカンファレンスで発表してみたら、思ったよりも反響があって、みんなが使い始めてしまった、くらいの流れだったと思います。

さて、そんなRecoilですが、残念な話がありました。

残念ながら、2022年10月にRecoilの主要メンテナの@drarmstr氏がMeta社の一斉レイオフで解雇された

Jotaiで快適フロントエンド開発 | 株式会社ヌーラボ(Nulab inc.)

主要メンテナの解雇というのは、まあまあの事故ですよね……

移行先のライブラリとして考えられるのは、上記の記事でも紹介されている「Jotai」です。

jotai.org

元々Recoilにインスパイアされて生まれたライブラリとのことなので、Recoilのいいところはある程度受け継いでいます。本書のサンプルとしては、まずRecoilを使ってみるのがいいと思いますが、少し慣れてきたら、Jotaiで書き換えてみるのも、いいエクササイズになるかもしれません。

React Routerの知識が活きるアプリケーションフレームワークもある

本書では、シングルページアプリケーション(ブラウザ上だけで動くアプリケーション)の中で画面遷移を行うために、React Routerの利用方法が70ページに渡る大ボリュームで解説されています。

しかし、残念なことに、その3つ後ろの章で解説されるアプリケーションフレームワークはNext.jsであり、React Routerで学んだ知識の大半はそのまま使うことができず、Next.jsのルーティングの癖を改めて学ぶことになります。

Next.jsは世界で最も使われているReact向けのアプリケーションフレームワークですので、本書の選択は間違っていません。間違ってはいないのですが、もし幻のChap 12があったとしたら、ぜひ解説してほしかったアプリケーションフレームワークがあります。

それはRemix(リミックス)です。

remix.run

Remixは、React Routerの開発チームが作った、ルーティングと通信をより快適に統合させながらブラウザとサーバーの通信をスッキリさせるためのフレームワークです。現在は開発チームが丸ごとShopifyに買収され、RemixはShopifyの公式フレームワークHydrogen v2のベースとなりました。

shopify.dev

Remixをおすすめしたいのは、なにも開発チームが同じだから、という理由ではありません。Remixのルーティングは、React Routerによって実現されているので、Remixの画面遷移にはReact Routerの知識がとても役に立つのです。

URLのパスを決定する方式だけはNext.jsとそっくりな、ファイルとフォルダによる仕組みを使っていますが、それ以外の部分はかなりReact Routerらしい機能が露出しており、React Routerを学んだ人には親しみ深く感じられることでしょう。 useHistory()useParams() といったフックを利用する際には react-router-dom からインポートしますし、階層構造になっているルート*1では <Outlet /> をプレースホルダーとして配置します。

一通り本書の内容を実践した上で「React Routerの空気感もいいなあ」と思われた方がいらっしゃいましたら、Remixのチュートリアル(英語)にチャレンジしてみていただけると、Remix推しとしてはちょっと嬉しいです。

remix.run

remix.run

これは宣伝ですが、本書著者の山田さんに編集してもらいながら、CodeZineにRemixの記事を連載しているので、興味があればこちらもお読みください……!!!

codezine.jp

まとめ

本書の内容は実際よくできており、Reactの初学者だけではなく、React 3年生くらいのジュニアエンジニアであっても多くのことを学べる良書に仕上がっていると思います。ちょっと分厚くてお高いですが、それを補って余りある基礎知識を得られますので、ぜひ読んでみてください。

おまけ

実は、なんで献本をもらえたのか全くわかっていませんw

普段、著者の山田さんが主宰しているWINGSプロジェクトでReact関連の記事を書かせてもらっていて、山田さんには編集者として忌憚のないご意見をいただいているので、その辺の経験がこの本に活きたりしたのかなあ、そうだといいなあ。

2023.9.28 10:36追記

P264の参考書籍のコラムに、僕のRemix連載を載せてくださっていました!ちゃんと僕とご縁のある本だった!ありがたい!

codezine.jp

参考書籍にRemix連載を記載していただきました!

*1:RemixではNested Routesと呼びます

JavaScriptとDIについての雑文

JavaScriptでDIコンテナってどうなの?という話題について雑に書きます。↓の話題について意見をくれと某所で言われたのでざっくり意見を書きます。

mond.how

DIコンテナ(≒依存性注入自動化フレームワーク)の発祥の地といってよさそうなJavaでは、DIコンテナでも使わないと依存性注入がやりづらいという言語上の制約があったために、DIを実現するためにはDIコンテナが事実上必須だった、みたいな雑な認識をしています。

しかし、JavaScriptのように関数が第一級市民として扱われる(関数を値として引数に渡せる)言語では、依存性の注入や差し替えが概ね容易であることが多い(DIコンテナがなくてもDIを実現しやすい)ため、DIコンテナ的なフレームワークを導入する旨みはJavaと比べると薄めなのかなと思います(ふわっとした発言)。実際、DIコンテナを内蔵しているNestJSを使ってみると、規模次第では便利っぽいけど、規模次第では煩雑さが目立つ(exportsやprovidersを登録するのめんどい)なあという印象です。

素朴なDIについて想いを馳せる

僕がDIでやりたかったこと(だと自分では思っている)を素朴に思い出してみます。

例として、次の fnA()fnB() への依存性を持っており、モックが原則不可能です*1

/* 依存性がある関数A */
import fnB from './b.ts';

export function fnA(a: number) {
  const b: Date = fnB(a);
  b.setDate(1);
  return b;
}

/* 使い方 */
const dateA: Date = fnA(1); // fnBの挙動をモックできない

一方、次の fnC() は↑と同じ処理を表していますが、 fnB() への依存性を持っていません。

/* 依存性を注入している関数C */
export function fnC(a: number, fnX: (a: number) => Date) {
  const b: Date = fnX(a);
  b.setDate(1);
  return b;
}

/* 使い方 */
import fnB from "./b.ts";

const dateC: Date = fnC(1, (a) => fnB(a)); // 第二引数を差し替えることでfnBをモック可能

fnC では、第二引数で fnB() 相当の関数 fnX() を外から注入しています。これも依存性の注入=DIと呼んで差し支えないでしょう。上記の例では fnB() がそのまま実行されるだけですが、テストコード等では次のような書き方もできます。

const actual: Date = fnC(1, (a) => new Date('2023-01-15')); // fnXの挙動を固定する

expect(actual).toBe(new Date('2023-01-01'));

fnX() が内部的に fnB() を利用しない形に差し替え、常に固定の結果を返すようにしました。これで fnB() の実装を気にせず、 fnC() 固有の挙動のテストに集中することができます。

これは素朴な例です。もっとDIコンテナが欲しくなるような複雑なケースもあるかとは思いますが、少なくとも僕は欲しいDIはこの素朴な例を少し複雑にした程度に収まることが多めです。

まとめ

DIという概念で僕が最低限やりたいことは、前述のように素朴なものです。もっと複雑なケースではDIコンテナが必要になるケースもあるかもしれませんが、素朴なケースでDIコンテナを持ち出すのは嫌だなあと思います。

用法容量を守って、必要なDIを必要な分だけやっていきましょう。

*1:webpack等でimport元を差し替えてテスト用モジュールに差し替えるようなハックはできますが、テスト用途で気軽に使うには実装コストが見合わないように思います

ビアリー IPA STYLEを一番のヤツで作った至高のビール煮で飲む

Beer Advent Calendar 2022 - Adventarの19日目とバズレシピ Advent Calendar 2022 - Adventarの20日目を一緒にやっちゃいます。

バズレシピ19日目を読んで、僕もそろそろリュウジが使ってるおろし金を買おうかなあという気持ちになりました。

さて今回は、バズレシピのビール煮(ちゃんとビールで作ったやつ)を食べながらビールテイスト飲料を楽しむという倒錯的な食事を楽しみました。

ビール煮でビアリーIPAを飲む

ビアリーIPA STYLE

ビアリー IPA STYLEは、ビールテイスト飲料ビアリーの10月に発売された新味です。

www.asahibeer.co.jp

たまたまスーパーで見かけたので飲んでみたのですが、これがまたびっくりする旨さでした。

しっかりした苦味があって、ビールテイスト飲料とは信じられないくらいです。ビアリーは普通にビールを作った後でアルコールを抜く製法なので、ほぼビールな味が出しやすいのかもしれませんね。

ビアリー IPA STYLE

原材料を見ると、酒類ではないのをいいことに(?)麦芽がモリモリと使われている様子が窺えます。もしかしてホップもまあまあ入っているのでは……?

麦芽とホップがモリモリ

そして重要なのは、ゼロカロリーは目指していないので、それなりにカロリーや糖質が入っているということです。やっぱり旨みは脂肪と糖から生まれるので、これは仕方ないですね(遠い目)。

至高のビール煮

めちゃくちゃ旨いビアリー IPA STYLEをより美味しく飲むためにはどうしたらいいのか、私は考えました。

ビール(テイスト飲料)に合うのはやはりビール! ということで、ビールで作る最高の料理を作ることにしました。

www.youtube.com

材料は次の写真の通りです。近所のスーパーで豚肩ロースブロックが安く売っていて助かりました。

至高のビール煮の材料

飲むのはビールテイスト飲料ですが、料理の材料には妥協しません。一番のヤツ!(C.V.大蛇丸)です。

肉に焼き色をつけて〜

焼き色をつける

飴色玉ねぎとコンソメとビールを入れて煮込んだら〜

煮込む

あらヤダ美味しそうヤダー

小一時間煮込んだやつ

実食

というわけで冒頭の写真になったのでした。

マリアージュ!

ビールの旨みが染み込んだ肉を、ビールの旨みを忠実に残したビールテイスト飲料で流し込む! 美味しくないわけがないでしょう!

ちなみに僕は夕食の後にも仕事をすることが多いのですが、ビアリーなら飲んだ後でも仕事に支障がなくていいですね。晩酌要員として優秀です。

まとめ

というわけでバズレシピとビールという二つのアドベントカレンダーを繋いだテーマでやってみました。

ビール好きのみんな!飲みたい気持ちはわかるけど、ビール煮も旨いから作ってみてくれよな!

米消滅鶏キャベツ

バズレシピ Advent Calendar 2022 - Adventarの6日目です。

生協で毎週キャベツが家に届くので、キャベツの消費方法に頭を悩ませることが多いです。そんな時は 米消滅鶏キャベツ にお任せ!

youtu.be

鶏肉は削ぎ切りするし、味噌と絡めて揉み込むし、キャベツはバターと一緒にレンチンするしで、そこそこ手間のかかるレシピではあります。

それでも、濃厚に味噌を絡めて炒めた鶏もも肉が美味しくないわけがないんですよ。そこに蒸したキャベツまで絡んだら優勝間違いなしなんですよ。

優勝する要素しかない

これはかなり子供ウケもいいので、キャベツの使い道に迷ったときはまた作ります。

それではまた次回!