Java 自动执行命令
这段代码混合了命令和生成器模式:Java 自动执行命令,java,design-patterns,dsl,Java,Design Patterns,Dsl,这段代码混合了命令和生成器模式: CommandBuilder.create("one value").execute(); CommandBuilder.create("another value").withBigDecimal(BigDecimal.ZERO).withNumber(123).execute(); 它所做的只是简单的打印: one value another value 123 0 目标是摆脱execute()方法。这意味着在最后一个with xxx(
CommandBuilder.create("one value").execute();
CommandBuilder.create("another value").withBigDecimal(BigDecimal.ZERO).withNumber(123).execute();
它所做的只是简单的打印:
one value
another value 123 0
目标是摆脱execute()
方法。这意味着在最后一个with xxx()
方法之后(或者没有任何with xxx()
),代码将自己进行打印
以下是当前代码:
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()
method完全实现构建器模式),但在这种情况下,如果始终使用链中的最后一个方法,则不会出现导致返回的问题
我认为真正的问题是:
如何将评估延迟到整个生成器方法链处理完毕?您可以这样执行smth: 导入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中没有其他解决方案,因为您必须调用执行方法。使用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));
我喜欢你的设计——这是最简单、最清晰的方式。然而,它改变了API。我必须说,当使用最后一种方法(消费者管理所有参数)时,您无法在编译时强制使用强制参数。所以第一次使用最合适。