这段代码是命令和构建器模式的混合:
CommandBuilder.create("one value").execute();
CommandBuilder.create("another value").withBigDecimal(BigDecimal.ZERO).withNumber(123).execute();
所有这一切都是简单的印刷:
one value
another value 123 0
目标是摆脱execute()
方法。这意味着在最后withXXX()
方法之后(或没有任何withXXX()
),代码将自行进行打印。
以下是当前代码:
import java.math.BigDecimal;
public class CommandBuilder {
private final String value;
private Integer number;
private BigDecimal bigDecimal;
private CommandBuilder(String value) {
this.value = value;
}
public static CommandBuilder create(String value){
return new CommandBuilder(value);
}
public CommandBuilder withNumber(Integer number){
this.number = number;
return this;
}
public CommandBuilder withBigDecimal(BigDecimal bigDecimal){
this.bigDecimal = bigDecimal;
return this;
}
public void execute(){
StringBuilder sb = new StringBuilder();
sb.append(value);
if(number != null){
sb.append(" ").append(number);
}
if(bigDecimal != null){
sb.append(" ").append(bigDecimal);
}
System.out.println(sb);
}
}
这在java中是否可行?
编辑附加信息
也许我的错误在于我没有提供有关意图的任何信息。我试图模糊这个问题,不要让它难以理解,也不能过于宽泛地回答。
所以这段代码就是DSL。这是命令只执行操作的最简单情况(例如,在数据库中存储一些信息)。另一种情况是命令必须返回一个值(使用build()
方法完全实现Builder模式) - 但在这种情况下,如果总是在链中的最后一个方法,则没有问题导致返回。
我认为真正的问题是: 如何延迟评估直到整个构建器方法链被处理?
答案 0 :(得分:1)
你可以用lambda得到你想要的东西:
import java.math.BigDecimal;
import java.util.function.Consumer;
class CommandBuilder {
private final String value;
private Integer number;
private BigDecimal bigDecimal;
private CommandBuilder(String value) {
this.value = value;
}
public static void createAndExecute(String value, Consumer<CommandBuilder> consumer){
CommandBuilder builder = new CommandBuilder(value);
consumer.accept(builder);
builder.execute();
}
public CommandBuilder withNumber(Integer number){
this.number = number;
return this;
}
public CommandBuilder withBigDecimal(BigDecimal bigDecimal){
this.bigDecimal = bigDecimal;
return this;
}
public void execute(){
StringBuilder sb = new StringBuilder();
sb.append(value);
if(number != null){
sb.append(" ").append(number);
}
if(bigDecimal != null){
sb.append(" ").append(bigDecimal);
}
System.out.println(sb);
}
}
并像这样使用它:
CommandBuilder.createAndExecute("something", builder -> builder.withNumber(1));
我想最好在消费者中设置值,如下所示:
CommandBuilder.createAndExecute(builder -> builder.withValue("something").withNumber(1));
答案 1 :(得分:0)
你可以这样做: import java.math.BigDecimal;
public class CommandBuilder {
private final String value;
private Integer number;
private BigDecimal bigDecimal;
private CommandBuilder(String value) {
this.value = value;
}
public static CommandBuilder create(String value){
return new CommandBuilder(value);
}
public static CommandBuilder create(String value, boolean exec){
CommandBuilder builder = create(value);
if(exec){
execute();
}
return builder;
}
public CommandBuilder withNumber(Integer number){
this.number = number;
return this;
}
public CommandBuilder withNumber(Integer number, boolean exec){
CommandBuilder builder = withNumber(number);
if(exec){
execute();
}
return builder;
}
public CommandBuilder withBigDecimal(BigDecimal bigDecimal){
this.bigDecimal = bigDecimal;
return this;
}
public CommandBuilder withBigDecimal(BigDecimal bigDecimal, boolean exec){
CommandBuilder builder = withBigDecimal(bigDecimal);
if(exec){
execute();
}
return builder;
}
public void execute(){
StringBuilder sb = new StringBuilder();
sb.append(value);
if(number != null){
sb.append(" ").append(number);
}
if(bigDecimal != null){
sb.append(" ").append(bigDecimal);
}
System.out.println(sb);
}
}
然后使用它如下:
CommandBuilder.create("anothervalue").withBigDecimal(BigDecimal.ZERO).withNumber(123, true);
这是一种解决方法,但我确实认为Java中没有其他解决方案,因为不得不以某种方式调用执行方法。