【问题标题】:How to avoid duplicate code inside constructors? Java如何避免构造函数中的重复代码?爪哇
【发布时间】:2021-10-16 20:30:24
【问题描述】:

通常在编写对象时,我最终会创建相当长的构造函数或包含对象实例方法中已经存在的代码的构造函数(重复代码)。我知道我可以在构造函数中调用这些实例方法,但我也明白这样做是不好的做法。这是不安全的。如何在确保构造函数安全的同时避免构造函数中的重复代码?

目前,我正在复制纸牌游戏 Scopa。在我的游戏对象的构造函数中,我正在初始化所有实例变量、填充牌组、向玩家发牌以及向桌子发牌。我这样做是为了让游戏处于实例化后可以立即播放的状态。然而,正如我之前所说,很多这种逻辑都是重复的。例如,我有一个实例方法也可以向玩家发牌(在我必须发新牌的情况下)。

在阅读了不同的资料后,我认为下面的代码是一种更好的方法。虽然,我仍然不满意...基本上它保证了每次有人想要实例化一个新游戏时,他们必须调用三个实例方法才能使其处于可玩的初始状态。

public ScopaGame(
    final String playerName,
    final String computerName)
{
    deck = new Deck(); // creates an empty deck
    pile = new ArrayList<>();
    player = new Player(playerName);
    computer = new Player(computerName);
}
final ScopaGame game = new ScopaGame("Player 1", "Player 2");
game.refreshDeck(); // resets and shuffles the deck
game.dealToPlayers();
game.dealToTable();

这里避免使用构造函数是最好的解决方案吗?比如下面的代码?这里我创建了一个实例化和初始化对象的实例方法。有了这个,我可以将构造函数设为私有并强制调用者使用这个方法。

public static ScopaGame createGame(
    final String playerName,
    final String computerName)
{
    final ScopaGame game = new ScopaGame("Player 1", "Player 2");
    
    game.refreshDeck();
    game.dealToPlayers();
    game.dealToTable();
    
    return game;
}

谢谢,希望这是有道理的。洞察力受到高度赞赏。请提供具有无实例方法的构造函数和不实现重复代码的构造函数的解决方案。

【问题讨论】:

  • "我知道我可以在构造函数中调用这些实例方法,但我也知道这样做是不好的做法。这是不安全的。" - 不一定是这样.如果出现以下情况是不安全的: - 我们泄漏了一个过早的对象或 - 我们调用的方法既不是 private 也不是 final
  • (调用static方法也可以。)
  • 我通常喜欢将对象的这种初始化放在一个名为“init()”的私有方法中,我在构造函数中调用它,并且每当我希望重新初始化对象时。但是我不会把你调用的三个方法放在那里,我也认为它们不应该是构造函数的一部分,因为它们似乎特定于游戏本身
  • @Turing85 是的,我已经读到了。不过,作为一般规则,我想避免在构造函数中使用实例方法。我读过,在构造函数中拥有“业务逻辑”通常不是很好。这是什么意思?
  • 请阅读:Can I ask only one question per post? --- 我已经看到通过构造函数调用开始的大量计算。这就是这句话的意思。构造函数应该做它需要做的事情。不多不少,不多不少。你考虑过使用工厂方法吗?

标签: java constructor code-duplication


【解决方案1】:

创建方法是保证所有初始设置都得到妥善处理的好方法。只需将您的构造函数设置为私有并让它初始化您的字段。您的 createGame 方法看起来很好。如果你想一次只允许一个游戏实例,你可以考虑将它变成一个单例,尽管允许一个游戏的多个实例是有意义的,因为你可以允许玩家更改他的名字或面对一个“不同的”对手。

private ScopeGame(final String playerName,
    final String computerName) {
this.playerName = playerName;
this.computerName = computerName;
}


【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-14
    • 2013-07-08
    相关资源
    最近更新 更多