2

我最不喜欢工厂方法模式的方面是冗长的if/thencase语句几乎不可避免。如果你有很多类要解决,那就更糟了。我只是不喜欢冗长的 if/thens。

考虑以下示例:

public class StatementFactory 
{
    public static Statement createStatement(String stmtSql)
    {
        Statement rslt = null;

        String frstWord = stmtSql.split("\\s+")[0].toUpperCase();

        if(frstWord.equals("SELECT"))
        {
            rslt = new SelectStatement(stmtSql);
        }
        else if(frstWord.equals("UPDATE"))
        {
            rslt = new UpdateStatement(stmtSql);
        }
        else if(frstWord.equals("INSERT"))
        {
            rslt = new InsertStatement(stmtSql);
        }
        else if(frstWord.equals("DELETE"))
        {
            rslt = new DeleteStatement(stmtSql);
        }

        return rslt;
    }
}

我想做的是有一个静态 Map 将frstWord映射到不同Statement实现的构造函数的指针,这样我就可以从映射中获取给定frstWord的指针并构造一个新实例,而不是拥有这个 if/then ugliness . 当然,现在可以使用反射来完成,但它比 if/then 更难看。

我的问题是:我可以期待Java 8中的闭包为我解决这个问题并提供上述所需的功能吗?

4

3 回答 3

5

即使在 Java SE 7 中,您也可以将其编写为:

    switch (frstWord) {
        case "SELECT": return new SelectStatement(stmtSql);
        case "UPDATE": return new UpdateStatement(stmtSql);
        case "INSERT": return new InsertStatement(stmtSql);
        case "DELETE": return new DeleteStatement(stmtSql);
        default: throw new IllegalArgumentException();
    }

没有必要对这类事情大发雷霆。

于 2013-02-25T20:49:20.137 回答
3

就像是

static Map<String, Function<String,Statement> map = new HashMap<>();
static
{
    map.put("SELECT", SelectStatement::new);
    // etc...
}

public static Statement createStatement(String stmtSql)
{
    ...
    return map.get(fstWord).apply(stmtSql);
}

当然,你可以在 Java 7 中用匿名内部类做类似的事情,这有点罗嗦。


有关构造函数参考,请参阅http://cr.openjdk.java.net/~briangoetz/lambda/lambda-state-final.htmlSelectStatement::new的第 9 节

于 2013-02-25T20:33:53.253 回答
0

You can do this without closures

interface StatementCreator<T> {
    T createStatement(String sql);
}

public class SelectStatementCreator implements StatementCreator<SelectStatement> {

    SelectStatement createStatement(String sql) {
        return new SelectStatement(sql);
    }
 }

similarly for the update, insert and delete statements. Then you map is created static or singleton or whatever...

static Map<String, StatementCreator<?>> factories = new HashMap<>();

static {
    factories.add("SELECT", new SelectStatementCreator());
}

Then pick up the creator and execute it

return map.get(frstWord).createStatement();

Ta Da!

于 2013-02-25T20:43:06.260 回答