例えば、if〜instanceofを避ける(2)

例えば、if〜instanceofを避ける(1) - 都元ダイスケ IT-PRESSの続き。

解決策は幾つかある。とりあえず今回は1つ紹介。

public enum Processor {
	
	LIST(List.class) {
		
		@Override
		public void process() {
			// List用処理
		}
	},
	
	MAP(Map.class) {
		
		@Override
		public void process() {
			// Map用処理
		}
	};
	
	private final Class<?> clazz;
	
	private Processor(Class<?> clazz) {
		this.clazz = clazz;
	}
	
	public abstract void process();
	
	public static Processor get(Object obj) {
		for (Processor processor : values()) {
			if(processor.clazz.isAssignableFrom(obj.getClass())) {
				return processor;
			}
		}
		throw new RuntimeException();
	}
}

こんな処理クラスを用意して、

Object foo = ...;
Processor.get(foo).process();

とすることで対処できる。さすがに、MapやList内に処理内容を書くことはできないけど、こうやって処理を分離しておくことはできる。追加でSet用の実装が必要になった時も、この列挙型に要素を追加し忘れればRuntimeExceptionで気づく事ができるだろう。

ネタ元は(確か)コレ。enumをもうちょっと使う - しげるメモの「コンストラクタの引数から定数を逆引きする」って項の変形ですね。