質問: this.calculator.calculate(); //resultに無効値が返ってくることもあるので、無効値の定数をどこかに定義したい。 //インターフェイスに定義すると怒られる。たかが1個の定数を定義するためにenumや定数クラスを作りたくない。 //実体クラス側に定数を定義すると、DI注入の意味がないし、ICalculatorの実体クラスが増える度に定数を定義しなければならない。 } } ```
回答: 解決済みですが・・・ インターフェースの主な目的は「機能を提供する手段としてのメソッド」を規定することで、メソッドの規定の基本はシグナチャーなので、シグナチャーだけで規定を完結する(つまり型だけによって規定する)ために、戻り値の型をintではなく次のようにするという選択もあると思います。 ``` // (A) interface ICalculator { Optional calculate(); } // または // (B) interface ICalculatorB { OptionalInt calculate(); } // もっとさぼるなら // (C) interface ICalculatorC { Integer calculate(); } ``` intでは表現しきれない結果を無理にint型にしたためにINVALID_VALUEなんて特殊な値を定義しなくてはならないわけで、そんな値を定義しなくてもよいように「あり得る状況を全て表現できる型」を用いるわけです。 蛇足: (C)は特殊状況を悪名高き(?)nullで表現するので、チェックを忘れてもコンパイル時に気づけないことも多く、実行時にNPEに遭遇なんてことにもなりますが、(A), (B)ではチェックし忘れの可能性は排除できます。ただし(A)ならmapを用いて ``` ICalculator calculator = ...; String s = calculator.calculate() .map(v -> String.format("%,7d", v)) .orElse("---,---"); System.out.println(s); ``` などと直接的なメソッドチェーンが書けますが(B)だとなぜかOptionalIntにmapが定義されてないため上記のようには書けません。個人的にはそうまで低水準な機能を設計しているのでないかぎりprimitiveにこだわらずに(A)を用いたほうが好みです。