繁体   English   中英

Java:抽象 class 与构建器模式

[英]Java: Abstract class with builder pattern

我希望这不是重复的; 我知道有一些类似名称的问题,但似乎都没有解决我的问题。

我有多个完全相同的类——除了一种特定的方法。 所以我决定创建一个抽象父 class,我们称之为A A运行所有代码并有一个方法calculate() ,所有子类都实现了该方法。

到目前为止,一切都很好。 我的问题是,所有子类都需要很多可选参数,所以我决定使用以下构建器模式,而不是创建许多不同的构造函数:

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()消息返回A object,但是A当然不能被实例化。

所以对我来说,似乎有两种解决方案,但它们都不是最优的:

  1. Builder class 移至A的子类,以便可以实例化它们。 这将导致大量冗余代码,因为构建器设置的所有属性都是相同的。

  2. 使A不抽象。 但这将允许另一个用户实例化它,即使这不是它的预期目的。

我错过了什么吗? 我觉得应该有一个更优雅的解决方案,但我现在想不出一个......谢谢

由于没有A的实例(作为抽象类),因此A构建器只能构建 A 的某些非抽象子类A实例。 在抽象 class 级别拥有构建器通常让构建器根据构建过程中收集的参数决定要实例化A的哪个具体子类。

这种方法背后的想法是调用者对具体的 class 不感兴趣,只是因为它是A子类,并且构建器可以自由地提供最适合构建请求的实例。

如果您的情况不同,因为用户想要决定生成的 class,那么您将创建多个构建器,并且可能让它们从(抽象)父构建器继承公共部分。 但是在这种情况下,问问自己使用构建器是否比直接使用构造器有足够的好处来保证额外的样板代码。 通过构造函数,您可以立即免费获得 inheritance。

存在类似“构建器模式”的事实并不意味着它满足您的要求。

因此,总结一下我看到的选项:

  • A级有一个构建器,它决定(在build()方法中)要实例化哪个子类(如果您的用户对具体的 class 不感兴趣,只需“任何A实现”),
  • 有多个构建器,每个子类一个。 为了避免代码重复,它们可以从A class 级别的抽象构建器继承。 这为用户提供了对结果类型的完全控制。
  • 忽略构建器模式,并使用普通的旧构造器。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM