首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何对抽象超类的子类使用构建器模式来遵循最佳Java实践?

如何对抽象超类的子类使用构建器模式来遵循最佳Java实践?
EN

Stack Overflow用户
提问于 2017-09-29 08:12:57
回答 1查看 124关注 0票数 0
代码语言:javascript
运行
复制
// CommandBuilder.java
public class CommandBuilder {

 public String name; // required
 public String description = "Default Value"; //optional

 public CommandBuilder(String name) {
  this.name = name;
 }

 public CommandBuilder setDescription(String description) {
  this.description = description;
  return this;
 }

 public CommandBuilder build() {
  return this;
 }
}

// Command.java
public abstract class Command extends ListenerAdapter {

 private String name;
 private String description;

 protected abstract void execCommand(MessageReceivedEvent event);

 public Command(CommandBuilder builder) {
  this.name = builder.name;
  this.description = builder.description;
 }

@Override
public void onMessageReceived(MessageReceivedEvent event) {
   execCommand(event);
 }
}

// ExampleCommand.java
public class ExampleCommand extends Command {

 public ExampleCommand(CommandBuilder builder) {
  super(builder);
 }

 @Override
 protected void execCommand(MessageReceivedEvent event) {
  // ...
 }
}

// Bot.java
public class Bot() {

 public static void main(String[] args) {

  // ...
  jdaBuilder.addEventListener(
   new ExampleCommand(
    new CommandBuilder("Example Command").setDescription("You know it.").build();
   )
  );
  // ...
 }
}

所以,我需要一些关于代码风格的建议。以上大致是我在JDA中为一个不和谐的机器人设置的代码。jdaBuilder.addEventListener(Object)做什么或者MessageReceivedEvent是什么并不重要。

在使用继承类型Command构造对象时,我使用构建器模式来避免过多的构造函数重载,因为在我的实际代码中,Command类可以接受的不仅仅是两个参数。CommandBuilder的问题是,build()不能也不能返回Command类型的对象(因为它是抽象的),而是返回类型CommandBuilder本身,命令的每个子类都将其作为参数(然后传递给Command)。作为回报,问题是:

  1. 不需要调用build(),因为其他每个方法都会返回一个CommandBuilder
  2. 具有4-6参数的Command子类的实例化主要会变得非常混乱。

那么,解决这个问题的最好方法是什么?我曾想过使用接口,但是在我的抽象Command类中,有一些带有“默认”代码的方法,如果子类需要它,它们可以选择覆盖它(但它不是必需的!)这些默认方法利用了Command类的其他方法,因此我不能将它们作为真正的默认方法重构到接口中。

我的代码工作得很好,我只是觉得用实例化对象的方式,我在某个地方做了一个错误的转弯。对于如何重构或重写我的代码以遵循最佳Java实践,有什么建议吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-09-29 08:39:45

也许你应该像这样重构你的build()

代码语言:javascript
运行
复制
public <T extends Command> T build(Function<CommandBuilder, T> constructor) {
    return constructor.apply(this);
}

这种方式允许构建器接受任何构造函数引用,如

代码语言:javascript
运行
复制
FooCommand cmd = builder.build(FooCommand::new);

另外,您还可以添加适当的代码,以便允许反射。

代码语言:javascript
运行
复制
FooCommand cmd = builder.build(FooCommand.class);

也可以使用,但前者的优点是,如果没有匹配的构造函数,就会出现编译时错误。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46484535

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档