マイペースなプログラミング日記

DTMやプログラミングにお熱なd-kamiがマイペースに書くブログ

Re:Java, デザインパターン: Simple Factory

http://www.yukun.info/blog/2009/03/java-design-pattern-simple-factory.html
このプログラムをちょっといじってみた。やったことはパターンが増える度にelse ifが増えてしまうことの解消と、思わぬ文字列が来てしまったときの対処(NullNamer)。結局、パターンが増えてしまえばそれだけaddPatternを呼び出さないといけないのは、仕方ないか。そして正規表現なんて使ってしまってるけど、区切り文字だけを渡せばすむ話だったと今気づく。あと1つのif文を消すためにクラス(NullNamer)を増やしてしまったのも考え物かも。以下ソース

public class Main{
    public static void main(String[] args){
        NameFactory nameFactory = new NameFactory();
        Namer namer;

        namer = nameFactory.getNamer("String#indexOf");
        printName(namer);
        namer = nameFactory.getNamer("ArrayList.get()");
        printName(namer);
        namer = nameFactory.getNamer("Thread#run");
        printName(namer);
        namer = nameFactory.getNamer("NULL");
        printName(namer);
    }

    private static void printName(Namer namer){
        System.out.println("Class Name:" + namer.getClassName());
        System.out.println("Method Name:" + namer.getMethodName());
    }
}
import java.util.Map;
import java.util.HashMap;
import java.util.regex.Pattern;

public class NameFactory{
    private final Map<Pattern, Namer> namerMap;
    private static final NullNamer NULL_NAMER = new NullNamer("null", "null");

    public NameFactory(){
        namerMap = new HashMap<Pattern, Namer>();

        addPattern(".+#.+", new SharpNamer());
        addPattern(".+\\..+", new PeriodNamer());
    }

    private void addPattern(String strPattern, Namer namer){
        addPattern(Pattern.compile(strPattern), namer);
    }

    private void addPattern(Pattern pattern, Namer namer){
        namerMap.put(pattern, namer);
    }

    public Namer getNamer(String input){
        for(Pattern pattern : namerMap.keySet()){
            if(pattern.matcher(input).matches()){
                Namer namer = namerMap.get(pattern);
                namer.setInput(input);
                return namer;
            }
        }

        return NULL_NAMER;
    }
}
public abstract class Namer{
    protected String className;
    protected String methodName;

    public final String getClassName(){
        return className;
    }

    public final String getMethodName(){
        return methodName;
    }

    public abstract void setInput(String input);
}
public class NullNamer extends Namer{
    public NullNamer(String className, String methodName){
        this.className = className;
        this.methodName = methodName;
    }

    @Override
    public void setInput(String input){}
}
public class PeriodNamer extends Namer{
    // 「.」で名前を区切る
    @Override
    public void setInput(String str){
        int index = str.lastIndexOf(".");

        //すでに正規表現でチェック済みなのでif文はいらない
        className = str.substring(0, index);
        methodName = str.substring(index + 1);
    }
}
public class SharpNamer extends Namer{
    // 「#」で名前を区切る
    @Override
    public void setInput(String str){
        int index = str.lastIndexOf("#");

        //すでに正規表現でチェック済みなのでif文はいらない
        className = str.substring(0, index);
        methodName = str.substring(index + 1);
    }
}