Java:具有构建器模式的摘要 class
Java: Abstract class with builder pattern
我希望这不是重复的;我知道有一些类似名称的问题,但其中 none 似乎解决了我的问题。
我有多个 class 是完全相同的 - 除了一个特定的方法。所以我决定创建一个抽象父项 class,我们称它为 A
。 A
运行所有代码并有一个方法 calculate()
,所有子 class 都实现了。
到目前为止一切顺利。我的问题是,所有 subclasses 都有很多可选参数,所以我没有创建很多不同的构造函数,而是决定使用以下构建器模式:
public abstract class A {
private int foo;
private int bar;
public static class Builder {
private int foo;
private int bar;
public Builder(int foo) {
this.foo = foo;
}
public Builder bar(int bar) {
this.bar = bar;
return this;
}
public A build() {
return new A(this);
}
}
private A(Builder builder) {
this.foo = builder.foo;
this.bar = builder.bar;
}
}
我在我的项目中经常使用这个特定的模式并且它工作得很好,只要 class 不是抽象的。问题是build()
消息returns一个A
对象,但是A
,当然不能实例化。
所以对我来说似乎有两种解决方案,但其中 none 似乎是最优的:
将Builder
class向下移动到A
的子class中,这样它们就可以实例化了。这将导致大量冗余代码,因为构建器设置的所有属性都是相同的。
使A
不抽象。但这将允许另一个用户实例化它,即使这不是它的预期目的。
我错过了什么吗?我觉得应该有更优雅的解决方案,但我暂时想不出一个...谢谢
由于没有 A
的实例(作为抽象 class),A
构建器只能构建一些 none-抽象子 class 共 A
。在抽象 class 级别拥有构建器通常可以让构建器根据在构建过程中收集的参数来决定实例化 A
的哪个具体子 class。
该方法背后的想法是调用者对具体 class 不感兴趣,只是因为它是一个 A
子 class,而构建器是免费提供最适合建筑要求的实例。
如果您的情况不同,因为用户想要决定结果 class,那么您将创建多个构建器,并可能让它们从(抽象的)父构建器继承公共部分。但在这种情况下,问问自己使用构建器是否比直接使用构造函数有足够的好处来保证额外的样板代码。使用构造函数,您可以立即免费获得继承权。
“构建器模式”之类的东西的存在并不意味着它能满足您的要求。
所以,总结一下我看到的选项:
- 在
A
级别有一个构建器决定(在 build()
方法中)要实例化哪个子class(如果您的用户对具体 class,只是“任何 A
实现”),
- 有多个构建器,每个子class。为了避免代码重复,它们可以从
A
class 级别的抽象构建器继承。这使用户可以完全控制结果类型。
- 忽略构建器模式,使用普通的旧构造函数。
我希望这不是重复的;我知道有一些类似名称的问题,但其中 none 似乎解决了我的问题。
我有多个 class 是完全相同的 - 除了一个特定的方法。所以我决定创建一个抽象父项 class,我们称它为 A
。 A
运行所有代码并有一个方法 calculate()
,所有子 class 都实现了。
到目前为止一切顺利。我的问题是,所有 subclasses 都有很多可选参数,所以我没有创建很多不同的构造函数,而是决定使用以下构建器模式:
public abstract class A {
private int foo;
private int bar;
public static class Builder {
private int foo;
private int bar;
public Builder(int foo) {
this.foo = foo;
}
public Builder bar(int bar) {
this.bar = bar;
return this;
}
public A build() {
return new A(this);
}
}
private A(Builder builder) {
this.foo = builder.foo;
this.bar = builder.bar;
}
}
我在我的项目中经常使用这个特定的模式并且它工作得很好,只要 class 不是抽象的。问题是build()
消息returns一个A
对象,但是A
,当然不能实例化。
所以对我来说似乎有两种解决方案,但其中 none 似乎是最优的:
将
Builder
class向下移动到A
的子class中,这样它们就可以实例化了。这将导致大量冗余代码,因为构建器设置的所有属性都是相同的。使
A
不抽象。但这将允许另一个用户实例化它,即使这不是它的预期目的。
我错过了什么吗?我觉得应该有更优雅的解决方案,但我暂时想不出一个...谢谢
由于没有 A
的实例(作为抽象 class),A
构建器只能构建一些 none-抽象子 class 共 A
。在抽象 class 级别拥有构建器通常可以让构建器根据在构建过程中收集的参数来决定实例化 A
的哪个具体子 class。
该方法背后的想法是调用者对具体 class 不感兴趣,只是因为它是一个 A
子 class,而构建器是免费提供最适合建筑要求的实例。
如果您的情况不同,因为用户想要决定结果 class,那么您将创建多个构建器,并可能让它们从(抽象的)父构建器继承公共部分。但在这种情况下,问问自己使用构建器是否比直接使用构造函数有足够的好处来保证额外的样板代码。使用构造函数,您可以立即免费获得继承权。
“构建器模式”之类的东西的存在并不意味着它能满足您的要求。
所以,总结一下我看到的选项:
- 在
A
级别有一个构建器决定(在build()
方法中)要实例化哪个子class(如果您的用户对具体 class,只是“任何A
实现”), - 有多个构建器,每个子class。为了避免代码重复,它们可以从
A
class 级别的抽象构建器继承。这使用户可以完全控制结果类型。 - 忽略构建器模式,使用普通的旧构造函数。