一个单身人士课程来设计卡片的通用套牌?

时间:2016-05-21 12:37:14

标签: java multithreading oop design-patterns singleton

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

  

设计通用牌组的数据结构。解释如何将数据结构子类化以实现二十一点。

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

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 int而不是private static int ??
  • 为什么该班级没有“新”操作员?我们应该至少实现一个套件才能使用它吗?所以,我们应该有类似的东西:return new Suit.Heart; if(听!= null)
  • 如果单例类不是线程安全的话,我认为这是一个很大的问题吗?因为我们必须做一些事情来同时处理两个线程访问类。像急切的实例化或使用volatile关键字进行Double-checked锁定并仅针对第一次实例进行同步......我的意思是,有很多技术可以做到这一点,但是如果我们什么都不做,那么就OOD来说它会变得非常糟糕和表现,没有?

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

1 个答案:

答案 0 :(得分:1)

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

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

如果构造函数是公开的,那么使用您的代码的人可能会在运行时创建自己的Suit。这肯定会破坏二十一点的标准规则并导致任何人玩错误。

在编译时将值分配给Suits会增加编译时检查,避免错误传递无效常量,并记录允许的值。

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

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