Java 在调用任何函数之前,如何在fluent API中传递参数?
我有这样的课Java 在调用任何函数之前,如何在fluent API中传递参数?,java,Java,我有这样的课 public class AImpl implements A { private String variable = "init"; @Override public A choice(A... choices) { return this; } @Override public A execute() { variable = "execute"; return this;
public class AImpl implements A {
private String variable = "init";
@Override
public A choice(A... choices) {
return this;
}
@Override
public A execute() {
variable = "execute";
return this;
}
}
我可以这样使用它(简单的例子)
或者像这样(更复杂的示例,具有可变的期望值)
我正在努力实现的目标
每次有选择时,我都希望将变量的最后一个值
传播到每个新实例。这是一个复杂示例的图形版本,在这里我包围了我所称的传播
我的问题是什么
在调用任何其他函数之前(在上面的简单示例中调用execute
之前,因为此函数使用(并且可以修改)此变量),如何将此变量传播到选项列表中的所有对象
我尝试过的
- 我不能使用构造函数,因为我没有对变量的引用
public AImpl(String variable) {
this.variable = variable;
}
- 此代码将不起作用,因为变量将在所有函数之后设置
@Override
public A choice(A... choices) {
for(A a : choices) {
a.setVariable(variable);
}
}
- 我尝试使用
Builder
(例如,设置所有值,并仅在末尾创建实例,例如从选择函数)。但是将函数execute
或choice
(…execute().execute().choice()…
)链接起来是有意义的。因此,建筑商变得很难创建,而且可能变得非常大
- 我还尝试将变量移动到
上下文
类中,但如果在选项
中我有另一个选择(在更复杂的示例中),则该变量不起作用。这是我当前的上下文类
public class Context {
private static Context instance = null;
private String variable;
private Context(){};
public String getVariable() {
return variable;
}
public void setVariable(String variable) {
this.variable = variable;
}
public static void set(String variable) {
if(Context.instance == null)
Context.instance = new Context();
Context.instance.setVariable(variable);
}
public static String get() {
if(Context.instance == null)
throw new NullPointerException();
return Context.instance.getVariable();
}
}
问题在于,新的AImpl实例需要继承其“父”AImple实例的上下文,即调用choice()
的实例。您不能使用new
操作符执行此操作。相反,您应该有一个使用继承的变量创建实例的方法
public A[] createChoices(int count, A optionalDefaultValues...) {
// return an array of clones of itself (possibly with adjusted defaults)
}
我终于找到了一个基于Context
方法的有效解决方案(参见我的尝试?)
主要思想
有两个主要观点。第一种方法是将单个变量(在上下文对象内部)替换为一个堆栈
Stack<String> variables = new Stack<>();
第二个主要思想是每次创建新选项时复制堆栈顶部的值,并在每个选项结束时将其删除
我的代码
这是我的代码,如果它能帮助其他人。我肯定有很多事情要做,以改善它,但它解决了我原来的问题
- TestSo.java
public class TestSo {
@Test
public void testSo() {
AImpl.create().choice(
new ChoiceList()
.add(AChoice.create().execute())
.add(AChoice.create().choice(
new ChoiceList().add(AChoice.create())
))
.add(AChoice.create().execute().choice(
new ChoiceList()
.add(AChoice.create())
.add(AChoice.create())
))
);
}
}
- A.java
public interface A {
A choice(ChoiceList choices);
A execute();
}
- AAbstract.java
public class AAbstract implements A {
@Override
public A choice(ChoiceList choices) {
return this;
}
@Override
public A execute() {
String variable = Context.get();
//...
Context.set("execute");
return this;
}
}
- AImpl.java
public class AImpl extends AAbstract {
private AImpl() {
Context.set("init");
}
public static AImpl create() {
return new AImpl();
}
}
- java
public class AChoice extends AAbstract {
private AChoice() {
Context.duplicate();
}
public static AChoice create() {
return new AChoice();
}
@Override
public AChoice choice(ChoiceList choices) {
super.choice(choices);
return this;
}
@Override
public AChoice execute() {
super.execute();
return this;
}
}
- ChoiceList.java
public class ChoiceList {
private List<AChoice> choices = new ArrayList<>();
public ChoiceList add(AChoice choice) {
Context.remove();
choices.add(choice);
return this;
}
}
公共类选秀员{
私有列表选项=新建ArrayList();
公共唱诗班成员增补(阿乔伊斯选择){
Context.remove();
选择。添加(选择);
归还这个;
}
}
- Context.java
public class Context {
private static Context instance = null;
private Stack<String> variables = new Stack<>();
private Context(){};
public String peek() {return variables.peek();}
public String pop() {return variables.pop();}
public void fork() {variables.push(variables.peek());}
public void push(String variable) {variables.push(variable);}
public static void set(String variable) {
if(Context.instance == null)
Context.instance = new Context();
Context.instance.push(variable);
}
public static String get() {
if(Context.instance == null)
throw new NullPointerException();
return Context.instance.pop();
}
public static void remove() {
if(Context.instance == null)
throw new NullPointerException();
Context.instance.pop();
}
public static void duplicate() {
if(Context.instance == null)
throw new NullPointerException();
Context.instance.fork();
}
public static String read() {
if(Context.instance == null)
throw new NullPointerException();
return Context.instance.peek();
}
}
公共类上下文{
私有静态上下文实例=null;
私有堆栈变量=新堆栈();
私有上下文(){};
公共字符串peek(){return variables.peek();}
公共字符串pop(){return variables.pop();}
public void fork(){variables.push(variables.peek());}
public void push(字符串变量){variables.push(变量);}
公共静态无效集(字符串变量){
if(Context.instance==null)
Context.instance=新上下文();
Context.instance.push(变量);
}
公共静态字符串get(){
if(Context.instance==null)
抛出新的NullPointerException();
返回Context.instance.pop();
}
公共静态void remove(){
if(Context.instance==null)
抛出新的NullPointerException();
Context.instance.pop();
}
公共静态无效副本(){
if(Context.instance==null)
抛出新的NullPointerException();
Context.instance.fork();
}
公共静态字符串读取(){
if(Context.instance==null)
抛出新的NullPointerException();
返回Context.instance.peek();
}
}
您的问题不是很清楚……我认为您需要某种构建器对象来构造您所需的所有数据的表示形式,并且只在最后构建器构造真实的对象。好的,我将尝试重新构建我关于builder
的问题。当你说new AImpl[new AImpl()]
你的意思是new AImpl[]{new AImpl()}
?什么是count
?欲望清单的大小?我想应该是清单的大小。但是,如果你想把它作为一个论点来传递,那就取决于你了。也许您只需在varargs列表中将“new”A对象作为原型传递,并创建相同数量的对象。
public class AChoice extends AAbstract {
private AChoice() {
Context.duplicate();
}
public static AChoice create() {
return new AChoice();
}
@Override
public AChoice choice(ChoiceList choices) {
super.choice(choices);
return this;
}
@Override
public AChoice execute() {
super.execute();
return this;
}
}
public class ChoiceList {
private List<AChoice> choices = new ArrayList<>();
public ChoiceList add(AChoice choice) {
Context.remove();
choices.add(choice);
return this;
}
}
public class Context {
private static Context instance = null;
private Stack<String> variables = new Stack<>();
private Context(){};
public String peek() {return variables.peek();}
public String pop() {return variables.pop();}
public void fork() {variables.push(variables.peek());}
public void push(String variable) {variables.push(variable);}
public static void set(String variable) {
if(Context.instance == null)
Context.instance = new Context();
Context.instance.push(variable);
}
public static String get() {
if(Context.instance == null)
throw new NullPointerException();
return Context.instance.pop();
}
public static void remove() {
if(Context.instance == null)
throw new NullPointerException();
Context.instance.pop();
}
public static void duplicate() {
if(Context.instance == null)
throw new NullPointerException();
Context.instance.fork();
}
public static String read() {
if(Context.instance == null)
throw new NullPointerException();
return Context.instance.peek();
}
}