読者です 読者をやめる 読者になる 読者になる

fromScriptToScript

シナリオライターからプログラマーになった人のブログ。要するにずっとスクリプト。

int定数をナウなヤングにバカウケなEnumにリファクタリング

突然技術記事謎書いてみます。

今、保守してるシステムの定数の持ち方がイケてない。

いけてないこーど

public class Const {
	public static final int STATUS_HOGE = 0;
	public static final int STATUS_HIGE = 1;
	public static final int STATUS_HAGE = 2;
}

典型的なint定数パターンだ。
これを、こんな風にしたい。

いけてるこーど

public enum Const {                                                                                                               
	STATUS_HOGE(0,"こいつほげ"),                                                                                                      
	STATUS_HIGE(1,"こいつひげ"),                                                                                                      
	STATUS_HAGE(2,"こいつはげ");                                                                                                      
                                                                                                                                       
	int dbNum;                                                                                                                         
	String status;                                                                                                                     
	private Const(int dbNum, String status) {                                                                                     
		this.dbNum = dbNum;                                                                                                            
		this.status = status;                                                                                                          
	}                                                                                                                                  
                                                                                                                                       
	@Override                                                                                                                          
	public String toString(){                                                                                                          
		return this.status;                                                                                                            
	}                                                                                                                                  
                                                                                                                                       
	public int toDbNum(){                                                                                                              
		return this.dbNum;                                                                                                             
	}                                                                                                                                  
}

なんでenumのほうがいいのかは、以下のブログでよく説明されてるので、
そっちを見ていただければ。
このブログと違って立派な技術ブログなのでオススメです。

promamo.com

前提条件

  1. IDEは使える
  2. 定数クラスには、アプリケーション内すべての定数が書かれてる
  3. 他のツールは申請面倒すぎて使えない

さてはてどうしたものか。


段階1 あれ、そのままいけるんじゃね?

あんまりがっつり意識してenum使ったことが無かったので気づかなかったのだが、
Static定数とEnum、呼び出し時のシンタックスが一緒。

int定数呼び出し

 Const.STATUS_HOGE;

enum呼び出し

 Const.STATUS_HOGE;
//変更が必要ない!

これこのまま使えるんじゃね?

段階2 無理でした。。。

まあそんなに簡単だったらブログにしないっすよね。

	public void saveData(){
		insertDB(Const.STATUS_HOGE);
	}

	private void insertDB(int const){
                //定数をステータスとしてDBに登録
	}

上みたいなコードがぶっ壊れます。

問題は自分で認識できている点で三つ。

  1. 今までint定数を引数に取ってたメソッドがコンパイル通らなくなる。
  2. 引数の型を無理に直すと、DB登録メソッドが行かれる
  3. 定数の数自体が多く、使われてる個所も膨大。手作業で直すのだるい。しんどい。

解決策

①こんな感じで定数ごとにgrep置き換えをかける
置き換え前:Const.STATUS_HOGE
置き換え後:Const.STATUS_HOGE.toDbNum()

②他のリファクタリングの際に、随時toDbNum()を外す
(条件比較とか)

うーん……めんどくせえ……
突っ込みどころ満載なので、誰かマサカリ投げてください。
ありがちなリファクタリングなので、何か答えあるんじゃないかと。