如何在 Builder 设计模式中实现方法的条件可见性?
How to implement conditional visibility of methods in a Builder design pattern?
如何在 Builder 设计模式中更改方法的可见性?
例如我有这个生成器:
public class Builder {
public Builder a() {
//
return this;
}
public Builder b() {
//
return this;
}
}
用户可以使用 API 并执行此操作:
new Builder().a().b();
new Builder().a();
new Builder().b();
new Builder().b().a();
我想允许他仅在 a()
被调用时访问方法 b()
:
new Builder().a().b();
new Builder().a();
一个简单的示例可以是 SQL 请求生成器。你不应该被允许在 select()
.
之前调用 when()
如何操作?
如果我没有正确理解你的问题,你可以这样做:
public class Builder {
private boolean aProcessed;
public Builder() {
this.aProcessed = false;
}
public Builder a() {
//
aProcessed = true;
return this;
}
public Builder b() throws IllegalAccessException {
if (!aProcessed) {
throw new IllegalAccessException();
}
//
return this;
}
}
两种方法:StepBuilder 模式,提到了 here(感谢 Eritrean)和自定义模式,在后面描述。
StepBuilder
在您的构建器中 class,定义与您的建筑应具有的“步骤”一样多的界面。接口中方法的返回类型 returns 到下一个方法应该可用的类型。
这里b()
只能在a()
之后调用。
public class Builder {
/*
* next available methods are defined by
* the returned interface type
*/
private static interface AStep {
BStep a();
}
private static interface BStep {
void b();
}
private static class Steps implements AStep, BStep {
BStep a() {
//
return this;
}
void b() {
//
return this;
}
}
}
带有抽象的自定义方法class(我称之为:AbstractBuilder)
因为我无法使用 StepBuilder 方法定义相同的方法名称,所以我尝试了其他方法。
我定义了一个 main Builder
,其中包含第一个可调用方法(可见)、常用方法和 build()
方法(受保护,因为它只能通过其他 class如果需要的话)。
我定义了一个名为 AbstractBuilder
的抽象 class,具有 Builder
类型的属性和一个设置此属性的构造函数。
我定义了多少步骤就有多少构建器。所有这些构建器都扩展了 AbstractBuilder
,因此如果需要,可以通过在 Builder
实例上调用它来获得通用方法和结束方法。
看起来像这样:
public class AbstractBuilder {
protected Builder builder;
protected AbstractBuilder(Builder builder) {
this.builder = builder;
}
}
public class Builder {
public BStep a() {
//
return new BStep(this);
}
protected Object build() {
//
return null;
}
}
public class BStep extends AbstractBuilder {
protected BStep(Builder builder) {
super(builder);
}
public CStep b() {
//
return new CStep(builder);
}
public Object build() {
return builder.build();
}
}
public class CStep extends AbstractBuilder {
protected CStep(Builder builder) {
super(builder);
}
public BStep and() {
//
return new BStep(builder);
}
public DStep c() {
//
return new DStep(builder);
}
public Object build() {
return builder.build();
}
}
public class DStep extends AbstractBuilder {
protected DStep(Builder builder) {
super(builder);
}
public CStep and() {
//
return new CStep(builder);
}
public EStep d() {
// etc. ... return new EStep(builder);
}
public Object build() {
return builder.build();
}
}
使用此模式,您可以在每次调用后管理方法的可用性并使用“向后”循环:
Builder builder = new Builder();
builder.a().b().and().a().b().c().and().b().build();
如何在 Builder 设计模式中更改方法的可见性?
例如我有这个生成器:
public class Builder {
public Builder a() {
//
return this;
}
public Builder b() {
//
return this;
}
}
用户可以使用 API 并执行此操作:
new Builder().a().b();
new Builder().a();
new Builder().b();
new Builder().b().a();
我想允许他仅在 a()
被调用时访问方法 b()
:
new Builder().a().b();
new Builder().a();
一个简单的示例可以是 SQL 请求生成器。你不应该被允许在 select()
.
when()
如何操作?
如果我没有正确理解你的问题,你可以这样做:
public class Builder {
private boolean aProcessed;
public Builder() {
this.aProcessed = false;
}
public Builder a() {
//
aProcessed = true;
return this;
}
public Builder b() throws IllegalAccessException {
if (!aProcessed) {
throw new IllegalAccessException();
}
//
return this;
}
}
两种方法:StepBuilder 模式,提到了 here(感谢 Eritrean)和自定义模式,在后面描述。
StepBuilder
在您的构建器中 class,定义与您的建筑应具有的“步骤”一样多的界面。接口中方法的返回类型 returns 到下一个方法应该可用的类型。
这里b()
只能在a()
之后调用。
public class Builder {
/*
* next available methods are defined by
* the returned interface type
*/
private static interface AStep {
BStep a();
}
private static interface BStep {
void b();
}
private static class Steps implements AStep, BStep {
BStep a() {
//
return this;
}
void b() {
//
return this;
}
}
}
带有抽象的自定义方法class(我称之为:AbstractBuilder)
因为我无法使用 StepBuilder 方法定义相同的方法名称,所以我尝试了其他方法。
我定义了一个 main
Builder
,其中包含第一个可调用方法(可见)、常用方法和build()
方法(受保护,因为它只能通过其他 class如果需要的话)。我定义了一个名为
AbstractBuilder
的抽象 class,具有Builder
类型的属性和一个设置此属性的构造函数。我定义了多少步骤就有多少构建器。所有这些构建器都扩展了
AbstractBuilder
,因此如果需要,可以通过在Builder
实例上调用它来获得通用方法和结束方法。
看起来像这样:
public class AbstractBuilder {
protected Builder builder;
protected AbstractBuilder(Builder builder) {
this.builder = builder;
}
}
public class Builder {
public BStep a() {
//
return new BStep(this);
}
protected Object build() {
//
return null;
}
}
public class BStep extends AbstractBuilder {
protected BStep(Builder builder) {
super(builder);
}
public CStep b() {
//
return new CStep(builder);
}
public Object build() {
return builder.build();
}
}
public class CStep extends AbstractBuilder {
protected CStep(Builder builder) {
super(builder);
}
public BStep and() {
//
return new BStep(builder);
}
public DStep c() {
//
return new DStep(builder);
}
public Object build() {
return builder.build();
}
}
public class DStep extends AbstractBuilder {
protected DStep(Builder builder) {
super(builder);
}
public CStep and() {
//
return new CStep(builder);
}
public EStep d() {
// etc. ... return new EStep(builder);
}
public Object build() {
return builder.build();
}
}
使用此模式,您可以在每次调用后管理方法的可用性并使用“向后”循环:
Builder builder = new Builder();
builder.a().b().and().a().b().c().and().b().build();