純粋なクラス
2024/09/14
今、『なっとく!関数型プログラミング』という本を読んでいます。関数型プログラミングの考え方として重要視される概念として「純粋関数」というものがあります。『なっとく!関数型プログラミング』の中で、以下のように書かれています。
純粋関数の定義
- 関数の戻り値は常に1つだけ
- 関数は引数にのみ基ずいて戻り値を計算する
- 関数は既存の値を変更しない
この定義は、今まで良く見掛けたことがある関数型の説明で出てきていた「副作用がない関数」というものの明確な説明になっています。
純粋関数を使ったプログラミングは、多くの利点があります。
- テストし易い
- バグが入り込みにくい
- 宣言的な記述が増えて読み易い(これは慣れもあるので一概にはいえないかも)
- などなど
こんなに利点が多いなら、「純粋関数」という概念を、オブジェクト指向言語的に解釈すると、多くの利点を得ることができるかもしれません。思考実験的に、OOP版を考えてみました。OOPでのプリミティブな要素といえばクラスなので「純粋なクラス」とします。
純粋なクラス(仮)
- コンストラクタの引数とメソッドの引数に基いてメソッドの戻り値を計算する
- コンストラクタの呼び出しは外部の値を変更しない
- メソッド呼び出しは外部の値を変更しない
コンストラクタの引数とメソッドの引数が、全て同じ値が使われた場合には、メソッドの戻り値は同じ値になるという指針なら、「純粋関数」の思想をある程度受け継げてるんじゃないでしょうか?
例えば、クラスのメソッド処理でログを出力したら外部の値を更新しているとも言えてしまうのですが、コンストラクタの引数にロガーを渡すようにして、出力しているのはロガーなので自身のクラスの処理としては純粋なクラスに近づきます。こう考えると、Dependency injectionも「純粋なクラス」へ寄せるための手法であると考えることもできます。
完全に「純粋なクラス」として実装できるクラスだけを使ってアプリケーションを構築できるとは思いませんが、「純粋なクラス」に寄せることを意識すると、テストが書き易くなりそうです。
現実的な指針という意味では、『オブジェクト設計スタイルガイド』がお勧めです。