Pau*_*aul 6 java design-patterns
如何更改 Builder 设计模式中方法的可见性?
例如我有这个生成器:
public class Builder {
public Builder a() {
//
return this;
}
public Builder b() {
//
return this;
}
}
Run Code Online (Sandbox Code Playgroud)
用户可以使用 API 并执行以下操作:
new Builder().a().b();
new Builder().a();
new Builder().b();
new Builder().b().a();
Run Code Online (Sandbox Code Playgroud)
我只想允许他b()仅在a()被调用时访问方法:
new Builder().a().b();
new Builder().a();
Run Code Online (Sandbox Code Playgroud)
SQL 请求生成器就是一个简单的示例。when()之前不应该允许你打电话select()。
怎么做呢?
两种方法:StepBuilder模式,这里提到(感谢Eritrean),另一种是自定义模式,稍后描述。
\n步骤生成器
\n在构建器类中,定义与构建应具有的“步骤”一样多的接口。接口中方法的返回类型返回到下一个方法应该可用的类型。
\n这里b()只能在之后调用a()。
public class Builder {\n /*\n * next available methods are defined by \n * the returned interface type\n */\n private static interface AStep {\n BStep a();\n }\n\n private static interface BStep {\n void b();\n }\n\n private static class Steps implements AStep, BStep {\n BStep a() {\n //\n return this;\n }\n\n void b() {\n //\n return this;\n }\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n使用抽象类的自定义方法(我称之为:AbstractBuilder)
\n由于我无法使用StepBuilder方法定义相同的方法名称,因此我尝试了其他方法。
\n我定义了一个 main Builder,其中包含第一个可调用方法(可见)、通用方法和build()方法(受保护,因为如果需要,它只能通过其他类使用)。
我定义了一个名为 的抽象类,AbstractBuilder它具有 type 属性Builder和设置该属性的构造函数。
我定义了与我的步骤一样多的构建器。所有这些构建器都会扩展AbstractBuilder,因此可以通过在实例上调用通用方法和结束方法(如果需要)Builder。
它看起来像这样:
\npublic class AbstractBuilder {\n\n protected Builder builder;\n\n protected AbstractBuilder(Builder builder) {\n this.builder = builder;\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n\xc2\xa0
\npublic class Builder {\n\n public BStep a() {\n //\n return new BStep(this);\n }\n\n protected Object build() {\n // \n return null;\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n\xc2\xa0
\npublic class BStep extends AbstractBuilder {\n\n protected BStep(Builder builder) {\n super(builder);\n }\n\n public CStep b() {\n //\n return new CStep(builder);\n }\n\n public Object build() {\n return builder.build();\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n\xc2\xa0
\npublic class CStep extends AbstractBuilder {\n\n protected CStep(Builder builder) {\n super(builder);\n }\n \n public BStep and() {\n //\n return new BStep(builder);\n }\n\n public DStep c() {\n //\n return new DStep(builder);\n }\n\n public Object build() {\n return builder.build();\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n\xc2\xa0
\npublic class DStep extends AbstractBuilder {\n\n protected DStep(Builder builder) {\n super(builder);\n }\n \n public CStep and() {\n //\n return new CStep(builder);\n }\n\n public EStep d() {\n // etc. ... return new EStep(builder);\n }\n\n public Object build() {\n return builder.build();\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n通过这种模式,您可以在每次调用后管理方法的可用性并使用“向后”循环:
\nBuilder builder = new Builder();\nbuilder.a().b().and().a().b().c().and().b().build();\nRun Code Online (Sandbox Code Playgroud)\n