当单例设计模式优于静态类以及静态类优于单例设计模式时,会有哪些场景?
7 回答
这不是一个真正的非此即彼的场景。
单例是具有静态 getter 和私有构造函数的实例。它们不是静态类。
具有某些附加条件的单例是一种确保您只有一个类实例的方法。
所以第一个问题是。您是否需要一个实例,即这件事是否有状态,第二个问题是考虑到他们进行单元测试有多困难,您是否想要一个。
例如,看一下 Service Locator 模式。
通常单例优于静态类。
单例与静态类相反:
- 可以继承,也可以继承;
- 可以实现接口;
- 可以序列化;
- 可以传递给其他类;
- 可以处置。
如果您选择静态类,那么您选择具体,没有灵活性。但是,如果你使用单例,你必须记住让它的实例化是线程安全的。
如果您只使用类作为某些函数的容器,请使用静态类。但在大多数其他情况下,您最好使用单例设计模式,因为您可能希望重用该对象或实例化它作为一个非单例。
我从这个讨论中得到的最后一点: 1. 一个对象有一些状态。状态表示对象属性的当前值。所以,如果你想有一个场景,你想要有一些可以改变的状态并且想要只有一个实例,那么使用 Singleton 类。例如,假设有一个日志文件要在某些操作成功或某些异常时更新。要更新此日志文件,我们必须对其进行锁定以避免任何不一致的数据,并且可以通过 Singleton 类来实现。2.当您不需要对象的状态并希望在应用程序启动时将您的类加载到内存中并保持在那里直到应用程序的生命周期 - 使用静态类。
您可以使用静态类为您提供不需要任何状态以及不需要实例化对象的简单方法。
使用单例意味着您只想将一个对象实例化一次,然后您可以传递它并更改其状态。使用单例,您还可以继承或实现接口。
两者之间的主要区别在于单例可以实现接口,并且允许出于测试或运行时原因更改其行为。静态类是静态的,虽然它可以有状态,但要彻底改变它的行为是很困难的。
作为类的实例的单例可以实现接口,如果与期望该接口的方法一起使用,可以很容易地用不同的行为替换。
日志记录是两者的常见用法。
静态记录器不太可能记录到不同的介质(数据库、xlm 文件、文本文件、json、流、Web 服务),因为您要么必须为调用使用不同的 API,要么设置一些状态然后拥有所有这些方法中包含所有不同类型的持久性。
单例记录器可以实现 ILog,然后如果您需要从记录到数据库切换到记录到 Web 服务,您只需使用另一个类(可能是也可能不是单例)。
单例可用于缓慢地远离静态类。当你意识到你永远不会改变行为时,静态类可以替换单例。
两者都很难在自己身上进行测试。但是测试使用它们的其他类可能是个问题。特别是,一个静态类——在测试和生产时,在某些方面想要稍微不同的行为(比如日志记录,或者文件的源/目标是文件共享与共享点)并不是未知的。在这种情况下,让类成为单例可以更轻松地更改该行为。