2011年3月31日木曜日

enumを使いたおしたい

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

javaのenumについてです。

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

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

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

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

こういうのはいかが?
  1. package sample;  
  2.   
  3. import java.math.BigDecimal;  
  4.   
  5. enum NumberUtility {  
  6.   
  7.  SIMPLE {  
  8.   
  9.   @Override  
  10.   Integer createInteger(String x_str) {  
  11.    return Integer.valueOf(x_str);  
  12.   }  
  13.   
  14.   @Override  
  15.   BigDecimal createBigDecimal(String x_str) {  
  16.    return new BigDecimal(x_str);  
  17.   }  
  18.  },  
  19.   
  20.  QUIET {  
  21.   
  22.   @Override  
  23.   Integer createInteger(String x_str) {  
  24.    Integer result = null;  
  25.    if (x_str != null) {  
  26.     try {  
  27.      result = SIMPLE.createInteger(x_str);  
  28.     } catch (NumberFormatException e) {  
  29.     }  
  30.    }  
  31.    return result;  
  32.   }  
  33.   
  34.   @Override  
  35.   BigDecimal createBigDecimal(String x_args) {  
  36.    BigDecimal result = null;  
  37.    if (x_args != null) {  
  38.     try {  
  39.      result = SIMPLE.createBigDecimal(x_args);  
  40.     } catch (NumberFormatException e) {  
  41.     }  
  42.    }  
  43.    return result;  
  44.   }  
  45.  };  
  46.   
  47.  abstract Integer createInteger(String x_str);  
  48.   
  49.  abstract BigDecimal createBigDecimal(String x_str);  
  50. }  
  51.   
  52. abstract class Test {  
  53.   
  54.  void exec() {  
  55.   System.out.println("100 => " + getNumberUtility().createInteger("100"));  
  56.   System.out.println("10.0 => " + getNumberUtility().createBigDecimal("10.0"));  
  57.   System.out.println("null => " + getNumberUtility().createInteger("null"));  
  58.  }  
  59.   
  60.  abstract NumberUtility getNumberUtility();  
  61. }  
  62.   
  63. public class TestMain {  
  64.   
  65.  public static void main(String[] args) {  
  66.   
  67.   try {  
  68.    new Test() {  
  69.   
  70.     @Override  
  71.     NumberUtility getNumberUtility() {  
  72.      return NumberUtility.SIMPLE;  
  73.     }  
  74.    }.exec();  
  75.   } catch (Exception e) {  
  76.    System.out.println("catch exception. => " + e.getMessage());  
  77.   }  
  78.    
  79.   System.out.println();  
  80.   
  81.   try {  
  82.    new Test() {  
  83.   
  84.     @Override  
  85.     NumberUtility getNumberUtility() {  
  86.      return NumberUtility.QUIET;  
  87.     }  
  88.    }.exec();  
  89.   } catch (Exception e) {  
  90.    System.out.println("catch exception. => " + e.getMessage());  
  91.   }  
  92.  }  
  93. }  
enumの中にabstractメソッドがあって、その場で実装しています。こんなことができるんですねぇ。知りませんでした。
書いた内容について簡単に言うと、Utilityクラスの切り替えです。
Utilityの処理の役割としてはstaticなメソッドで実装したいのだけど、ロジックの違いをインスタンスで変えたいって感じです。

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

0 件のコメント:

コメントを投稿