java - 一个单例类来设计一副通用的牌?

标签 java multithreading oop design-patterns singleton

我正在阅读著名的破解编码面试书,现在我正在阅读关于 OOD(面向对象设计)的一章,其中包含这个问题:

design the data structures for a generic deck of cards. Explain how you would subclass the data structures to implement blackjack.

我想在这里向您展示一段我不太理解的代码:

public enum Suit { 
    Club (0),
    Diamond (1),
    Heart (2),
    Spade (3);

    private int value;
    private Suit(int v) {
    value = v;
    }

    public int getValue() {
    return value;
    }

    public static Suit getSuitFromValue(int value) {
    switch (value) {
    case 0:
        return Suit.Club;
    case 1:
        return Suit.Diamond;
    case 2:
        return Suit.Heart;
    case 3: 
        return Suit.Spade;
    default:
            return null;
    }
   }
  }

我发现了解设计模式,并且在代码中识别它们时遇到了一些困难。但是,当我们看到像本例这样的私有(private)构造函数时,它绝对意味着我们想要实现单例模式以拥有此类的唯一实例,不是吗?我认为这是合乎逻辑的,因为在一副牌中,我们每种类型只有一套套装(钻石、心形……)。

所以,如果(我不知道是否还有另一种情况,构造函数是私有(private)的),这个类是一个单例:

  • 为什么值只是 private int 而不是 private static int?
  • 为什么该类中没有“new”运算符?我们至少应该实例化一个套件才能使用它,不是吗?所以,我们应该有这样的东西: return new Suit.Heart; if(听到!=null)
  • 我认为如果单例类不是线程安全的,那是一个大问题,不是吗?因为我们必须做一些事情来处理两个线程同时访问该类。诸如急切实例化或使用 volatile 关键字进行双重检查锁定并仅在第一次实例化时进行同步之类的东西...我的意思是,有很多技术可以做到这一点,但如果我们对此不采取任何措施,就 OOD 而言,它可能会变得非常糟糕和性能,不是吗?

如果您能帮助我更好地理解这些要点,谢谢

最佳答案

枚举与 Java 中的类不同。它们具有比类更具限制性的特殊用途。

构造函数在枚举中是私有(private)的原因是因为与实例关联的值应该是预定义的。当您需要表示一组固定的常量(例如一周中的几天)时,枚举非常有用。您可以在编译时定义这些值,然后仅通过名称(MONDAY、TUESDAY 等)引用它们。

如果构造函数是公共(public)的,那么使用您的代码的人可能会在运行时发明自己的 Suit。这肯定会违反二十一点的标准规则,并给任何玩游戏的人带来错误。

在编译时将值分配给 Suits 可以增加编译时检查,避免因传入无效常量而产生错误,并且还记录允许的值。

示例中的静态方法是一个方便的实用程序,用于将整数转换为其相应的 Suit,但不是 Enum 的要求。

上面的类是线程安全的,并且枚举的创建也是线程安全的,因为它们是在枚举由 JVM“类加载”时初始化的,但您仍然可以在枚举中创建非线程安全的方法。

关于java - 一个单例类来设计一副通用的牌?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37363008/

相关文章:

java - JAVA中如何判断字符串数组中的单词是否相等

java - 将文本插入生成的 pdf 文档

java等待并通知

c# - 为什么在声明中隐式向上转换?

php - Zend Framework - 在oop原理中,方法 '$this->getRequest()->getPost()'如何工作?

java - 访问jar内的图像

java - 混淆for循环

c++ - 我的生产者消费者队列的任何明显问题或改进

java - Android 程序中的线程崩溃

c# - 创建了同名的类。这是如何运作的?