一个单例类如何使用接口?

12

我在很多地方读到过单例模式可以使用接口,但我无法理解。

5个回答

23

每个类都可以实现接口,而Singleton只是一个“普通”的类,它确保在任何时候只存在一个实例,除了其他可能实现的业务逻辑。 这也意味着Singleton至少有两个职责,这不是良好的面向对象设计,因为类应该只有一个职责并确保他们擅长处理这种职责,但这是另一个讨论话题。


为什么单例模式不是良好的面向对象设计?实际上,它是最常见的面向对象设计模式之一。 - Christian Vielma
2
@ChristianVielma:(是的,有点晚了)问题在于它创建了全局状态,就像全局变量一样,并且遭受类似的问题。例如,如果内部请求单例而没有外部知识,则很难测试类。您的生产数据库充满了垃圾/测试数据?检查单例。追踪错误?如果您有单例,因此具有全局状态,则不能仅关注有限范围;您必须牢记代码库。感谢单例。请注意,这是关于单例模式,而不是单例对象。常见用法并不意味着它必须是“好”的。 - code_dredd

10

类似于:

public interface MyInterface 
{
}

并且

public class MySingleton implements MyInterface
{
  private static MyInterface instance = new MySingleton();

  private MySingleton() 
  {
  } 

  public static MyInterface getInstance()
  {
    return instance;
  }
}

7
FYI,Java实现单例模式的最佳方式是使用单元素枚举。这种方法比公共字段更为简洁,并且它提供了免费的序列化机制以及反射攻击的安全性保障。虽然这种方法尚未被广泛采用,但了解一下也许会很有趣。 有关更多信息,请参阅Joshua Bloch所著《Effective Java》中有关此项内容的章节。 - nkr1pt
@Andrew:谢谢,我在 Stack Overflow 和日常工作之间来回忙碌,不小心错过了这个 :-) - Nick Holt
@nkr1pt:我通常尽量避免使用单例,但使用枚举是个好主意,谢谢指点。 - Nick Holt
@nkr1pt 我以前从未想过那种技术。 那确实是强大的,但惊人的简单。 它还极大地简化了引用,并使其非常直观。 - K.Barad

7
我认为我理解了你的问题。您想在接口中定义工厂方法(获取实例的静态方法)。但是,由于工厂方法无法在接口中定义,因此该逻辑将不起作用。
一种选择是拥有一个保存该静态方法的工厂类。因此将有三个类 第一个类用于保存静态方法 第二个是接口 第三个是具体类
但是我们不能使具体构造函数私有。
但是,如果您的基础设施有两个包,一个用于公共,另一个用于私有
在公共中定义接口,使具体类为包级别(没有任何访问修饰符),并使工厂类和静态方法为公共。
我希望这可以帮助到您。

0
一个单例模式有一个实例 - 它只有一个实例,永远不会有多个实例。你可能使用了一些静态成员来获取引用并确保它永远不会有多个实例,但在大多数情况下,这个类与任何其他类都是相同的。

0

基本上,单例类是一种只能实例化一次的类。

通过使用静态方法获取单例类的实例并限制对其构造函数的访问来实现单例类模式。

与使用接口的用法类似,它类似于任何其他类实现接口的方式。

同时,它也不应该允许克隆该对象。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接