まえがき
本書を書こうと思ったきっかけは、私自身のオープンソースプロジェクトでの経験でした。そのプロジェクトには、データをパイプラインのように順番に処理する部分がありました。オブジェクトは複数のステップを経る間に、何度も状態が変わったり、内容が書き換えられたりしていました。あるとき、この部分でメモリ使用量が異常に増える問題が起きました。その後、イミュータブルな型を使ってリファクタリングしたところ、処理全体の実行速度とメモリ使用量に明らかな改善が見られました。
そのリファクタリングでは良い結果が得られましたが、イミュータブルな型に変えれば必ずプログラムが速くなったり、メモリ使用量が減ったりするわけではありません。それでもこの経験から、イミュータブルなデータ設計の手法とトレードオフを一冊にまとめ、同じようにデータの変換や状態の変化を扱う開発者と共有したいと思うようになりました。
現在の LLM(Large Language Model、大規模言語モデル)を使えば、開発者が AI エージェントに「このプロジェクトの一部のクラスをイミュータブルな型にリファクタリングして」と伝えるだけで、コードの書き換えから関連するテストの作成まで任せられるかもしれません。
しかし、プロジェクトのどの部分にイミュータブル設計(immutable design)を採用すべきか、開発者はどう判断すればよいのでしょうか。どのような効果を期待し、その効果をどう検証すればよいのでしょうか。そして、AI が選んだ方法が適切かどうかを、どう見極めればよいのでしょうか。
実装とテストをすべて AI に任せたとしても、開発者には「設計の妥当性を見極める力」が必要だと私は考えています。何を改善したいのかを明確にし、変更後の結果を見て、その方法が適切だったかを判断する力です。本書を通じて、読者の皆さんがこうした判断力を身につける手助けもできればと思います。
経験豊富な C#/.NET 開発者にとっても、本書は使い慣れたコードを見直す機会になります。データは誰が作り、どこで変わり、どの処理で共有されるのか。こうした問いから出発し、なじみのある C# の機能を使うことで、データと状態遷移をより理解しやすくできます。
C# の record、init、パターンマッチングに、.NET のイミュータブルコレクションを組み合わせると、データと操作を分けて考えやすくなります。ただし、それぞれの機能の使い方を知っていることと、それらが設計にどのような変化をもたらすかを理解していることの間には、まだ隔たりがあります。本書が、その隔たりを少しでも埋める助けになれば幸いです。