-非公開メソッドにハードアクセスするパターン?
public interface Target { String getValue(); } public interface Processor { void process(Target target); }
こういうのがあったとして、以下が実装とします。
public class TargetImpl implements Target { private String _value; public String getValue() { return _value; } public void setValue(String value) { _value = value; } } public class ProcessorImpl implements Processor { public void process(Target target) { // キャストが発生、ぬるい。 ((TargetImpl)target).setValue("VALUE"); } }
TargetインターフェイスではAPIとしてgetValue()は定義していますが、setValue()は定義しておらず、API的に非公開とします。DI利用では実装クラスたるTargetImplにsetValue()を定義するケースがあるでしょう。影響範囲広いところでは書き込み可能で公開したくないけど、同じコーディングライフサイクル下で適切に管理されていれば、それでいいじゃん?と。
一方でそのTargetを取り扱いたいクラス、ProcessorImplでは、普通ならアクセスできず、具体的実装クラスにキャストしないといけない場合がでてきます。そこをDIコンテナに処理させる方法・要件もあるでしょうが、触りたいんじゃーというときに型がぬるくなるのが寂しい。ということで、以下のProcessor2インターフェイスのように、対象インターフェイスを継承した型パラメータで処理側の定義をうけとくといいかも。
public interface Processor2<T extends Target> { void process(T target); } public class Processor2Impl implements Processor2<TargetImpl> { public void process(TargetImpl target) { // キャストが無い! target.setValue("VALUE"); } }
どうかな?バイトコード的にはキャストですが。。。
コメントより。たしかにキャスト場所が代わってもらっただけかなぁ。あえて明示的なキャスト無しだと以下。
public class Main { public static void main(String[] args) { // 以下のProcessor2とTargetを取得するのは、 // ふつうならS2がやってくれるとして。。。 Processor2 proc = new Processor2Impl(); Target t = new TargetImpl(); // ここで型がぬるくなる! proc.process(t); System.out.println(t.getValue()); } }
万能ではないですね。