想象一下,我有一个很好的Deck课程,以最好的OO方式。它有卡片,有套装和等级,有Shuffle方法,等等。现在,我将有很多并发的Deck实例(比如这是一个赌场)。问题是:所有甲板上的每张卡都应该有不同的实例吗?
答案 0 :(得分:6)
Card对象可能最好实现为不可变对象。为了创建一张牌,你必须传递一个套牌和一个等级,这个套装和等级将永远不会改变。
从这个角度来看,由于这些对象没有改变,并且由于有一个设定的编号,因此实现包含所有52个可能的Card对象的单个静态集合是有意义的,并从其他对象访问这些卡类(使卡上的构造函数成为私有,这样就无法在Card类之外创建一个卡)。
这里真正的区别是卡本身不会执行任何操作,其他操作会对卡片起作用,因此制作单个卡片实例应该没问题。
答案 1 :(得分:4)
它被官方称为Flyweight模式,并首先在GOF“设计模式”中预先设定。在你的情况下应该非常有用。由于卡片永远不会改变,您甚至可以考虑将它们实现为Enums。
答案 2 :(得分:0)
这取决于你将如何使用这些卡片。但是,可能来自额外的Card实例的任何额外内存使用都是微不足道的 - 毕竟,每张卡只存储两个字节的数据。
答案 3 :(得分:0)
你问:“所有甲板上的每张卡都应该有不同的实例吗?”答案是不:您可以使用每张卡的单个实例并在所有套牌中共享它,即使它们在不同的线程上运行。原因是卡是不可变的,所以即使两个线程在同一张卡上调用card.getSuit(),它们的计算也不会干扰。
当然,如果您将卡类编写为真正不可变的,那么这是唯一的。只要您写入卡的某个局部变量,就会暴露自己的数据竞争。但我想不出这样做的理由,所以你应该安全。