java - 使数组不可变

标签 java oop immutability

我正在创建扑克模拟器用于学习目的,但在使 Deck 类不可变时遇到问题。

public class Deck {

     private final Card[] cards;
     private int cardCount;

     public Deck(@NotNull Card[] c) {
          this.cards = Arrays.copyOf(c, c.length);
          this.cardCount = c.length - 1;
     }

     public Deck shuffle() {
          // shuffle logic
          return new Deck(this.cards);
     }

     public Card pop() {
          return this.cards[cardCount--];
     }
     // other methods
}

Dealer 类保存 Deck 引用并实现发牌逻辑。

public class Dealer {

     private final Deck deck;

     public Dealer(@NotNull Deck d) {
          this.deck = d;
     }

     public void deal(@NotNull Holder<Card> h) {
          h.hold(deck.pop());
     }
     // other methods
}

如您所见,Deck 并不是完全不可变的,因为它保存 cardCount,每次调用 pop 时都会更新。 !注意 - cardCount 对外部不可见,而且 Card 类也是不可变的。

问题 1:此设计如何影响 Deck 不变性?

问题 2: future 可能产生什么影响?

问题 3:是否值得使 Deck 类完全不可变?如果是,那么如何?

感谢您的帮助。

最佳答案

这是少数几个不变性无济于事的情况之一。您似乎需要一个可变的共享状态,因为这是该 Deck 的全部目的。

要使其不可变,意味着每次有人弹出一张牌时,您都必须使用剩​​余的牌创建一个新的Deck。但是你无法控制旧的Deck(在移除顶部卡片之前),因此这可能仍然被某些客户端引用 - 在我看来,这违背了游戏的整个目的。

使用当前的实现,您可能会遇到多个线程的问题,因此请考虑使您的类线程安全。使用 java.util.Stack 而不是带有计数器的数组将是一个很好的首次尝试。

关于java - 使数组不可变,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38799624/

相关文章:

java - 生命周期配置未涵盖插件执行 : com. jayway.maven.plugins.android.generation2 :android-maven-plugin:3. 5.0:generate-sources

java - 如何调用类/静态方法

java - 如何在按回或打开 Activity 时隐藏滑动菜单

java - 为什么我的二进制到英文代码不能工作?

php - Ruby 相当于 PHP 的 $this

javascript - 如何从 Javascript 中的另一个私有(private)方法访问私有(private)方法

swift - init let 变量基于 bool 值

python - 如何为不可变类型实现 "__iadd__()"?

java - 关于书籍示例的问题 - Java 并发实践, list 4.12

java - 当我通过 JPA 运行查询时出现 MissingTokenException