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

enumごにょごにょ

Java

エディットグラフでの最短経路探索 - pocketberserkerの爆走の中で

if(current.type == NodeType.DELETE && parent.x == current.x && parent.y == current.y-1) {}
else if(current.type == NodeType.ADD && parent.x == current.x-1 && parent.y == current.y) {}
else if(current.type == NodeType.COMMON && parent.x == current.x-1 && parent.y == current.y-1) {}
else {
	current.prev = parent.prev;
	continue;
}

などとenum使ってるのに不格好な書き方をしていたので、修正がてら記事を投下しておく。
ここでの問題は何かと言うと「if文の条件式が長すぎる」ことである。しかも、条件式はNodeTypeの列挙定数毎に違うというから面倒くさい。
ここでNodeTypeの修正を行う。現状は以下の通り。

enum NodeType{
    DELETE,ADD,COMMON
}

if文の条件式をじっと眺めてみると……似たような式に見える(はず)。
なら話は簡単で、enumにメソッドを実装してしまえば良い。enumはクラスなのでメソッドなんて当たり前のごとく記述できます。
ここでは値の比較をしてるのでメソッドをなんとなくisPrevNodeと名付けた。
コツはenum内で抽象(abstract)メソッドを定義していること。このメソッドをオーバーライドすることで定数ごとに異なる動きを関連付けられる(定数固有メソッド実装、というらしい)。

enum NodeType {
	
    DELETE {
        boolean isPrevNode(SnakeNode current, SnakeNode parent){
            return (parent.x == current.x && parent.y == current.y-1);        }
    }, ADD {
        boolean isPrevNode(SnakeNode current, SnakeNode parent){
            return (parent.x == current.x-1 && parent.y == current.y);
        }
    }, COMMON {
        boolean isPrevNode(SnakeNode current, SnakeNode parent){
            return (parent.x == current.x && parent.y == current.y-1);        }
    };

    abstract boolean isPrevNode(SnakeNode current, SNakeNode parent);
}

後は呼び出し側を書き換えるだけ。

if(!current.type.isPrevNode(current, parent)) {
    current.prev = parent.prev;
    continue;
}

if文がすっきりしてるのっていいですよね!(enumが不格好になったのはこの際目をつむることにする)
そもそも意味不明なif文を書いてないで最初からこういう書き方にしておけよ、と自分に突っ込みたくなる今日この頃ですが。
Javaはもっと精進が必要なようです。
ちなみに寝不足でかなりの説明をはしょっているので悪しからず。