2011年3月31日木曜日

enumを使いたおしたい

こういうパターンはいかがでしょうか?という内容です。

javaのenumについてです。

先日、ふと、Effective Javaを読み直してenumについての認識を改めました。

enumの変数というのは、「唯一のインスタンス」
その結果、定数のようにイコールの演算子で一致するのです。

以前からそれは理解していました。
が、実は、思ってた以上に普通のクラスと同じで、インターフェースを実装できます。
さらには、mainメソッドを書いて実行することもできるのです。

これを定数としてしか使わないのは勿体無い。
ということで、有効活用をちょっと考えてみた。

こういうのはいかが?
package sample;

import java.math.BigDecimal;

enum NumberUtility {

 SIMPLE {

  @Override
  Integer createInteger(String x_str) {
   return Integer.valueOf(x_str);
  }

  @Override
  BigDecimal createBigDecimal(String x_str) {
   return new BigDecimal(x_str);
  }
 },

 QUIET {

  @Override
  Integer createInteger(String x_str) {
   Integer result = null;
   if (x_str != null) {
    try {
     result = SIMPLE.createInteger(x_str);
    } catch (NumberFormatException e) {
    }
   }
   return result;
  }

  @Override
  BigDecimal createBigDecimal(String x_args) {
   BigDecimal result = null;
   if (x_args != null) {
    try {
     result = SIMPLE.createBigDecimal(x_args);
    } catch (NumberFormatException e) {
    }
   }
   return result;
  }
 };

 abstract Integer createInteger(String x_str);

 abstract BigDecimal createBigDecimal(String x_str);
}

abstract class Test {

 void exec() {
  System.out.println("100 => " + getNumberUtility().createInteger("100"));
  System.out.println("10.0 => " + getNumberUtility().createBigDecimal("10.0"));
  System.out.println("null => " + getNumberUtility().createInteger("null"));
 }

 abstract NumberUtility getNumberUtility();
}

public class TestMain {

 public static void main(String[] args) {

  try {
   new Test() {

    @Override
    NumberUtility getNumberUtility() {
     return NumberUtility.SIMPLE;
    }
   }.exec();
  } catch (Exception e) {
   System.out.println("catch exception. => " + e.getMessage());
  }
 
  System.out.println();

  try {
   new Test() {

    @Override
    NumberUtility getNumberUtility() {
     return NumberUtility.QUIET;
    }
   }.exec();
  } catch (Exception e) {
   System.out.println("catch exception. => " + e.getMessage());
  }
 }
}
enumの中にabstractメソッドがあって、その場で実装しています。こんなことができるんですねぇ。知りませんでした。
書いた内容について簡単に言うと、Utilityクラスの切り替えです。
Utilityの処理の役割としてはstaticなメソッドで実装したいのだけど、ロジックの違いをインスタンスで変えたいって感じです。

Javaの言語仕様での、enumの実現方法がシンプルだからこそ、これだけの自由度があるのでしょう。
単純さが自由になります。

0 件のコメント:

コメントを投稿