Singleton与MonoState模式

当需要强制要求某个特定对象只能有单一实例时,可以使用Singleton或者MonoState模式完成.
首先看下两种模式的经典实现代码(代码摘自网络http://www.codethinked.com/the-monostate-pattern).

public class Singleton
{
    private static Singleton instance;
 
    private Singleton()
    {
    }
 
    public static Singleton Instance
    {
        get
        {
            if (instance == null)
            {
                instance = new Singleton();
            }
            return instance;
        }
    }
 
    public String DataItem { get; set; }
}
public class Monostate
{
    private static string dataItem;
    public string DataItem
    {
        get { return dataItem; }
        set { dataItem = value; }
    }
 
    public Monostate(){ }
}

对于Singleton模式,关注的是Structural Constraint,即只有一个实例. 该模式具有以下的优势:

  1. 跨平台.使用合适的中间件,能够把该模式扩展为跨多个JVM.
  2. 适合于任何类,针对任意普通类,通过简单的改造都可以成为Singleton的.
  3. 延迟创建.只有在第一次调用Instance来获取该单一实例时,才会进行实例的创建工作.

而对于该模式也有不少的抱怨, 最大的问题在于类创建方式的不透明性. 假设现在有一个Service类需要实现为Singleton的, 那么该Service的所有使用者都需要被通知到,要使用Instance方法(getter),而非new的方式来获取该类的实例.
另一个较为严重的问题是可能的内存泄露.如果在Singleton类中持有一些全局资源,那么是没有合适的时机进行资源释放的.

MonoState模式部分解决了Singleton模式的缺陷,它关注的是Behaviour. 该模式具有以下的优势:

  1. 透明性.对于创建者而已,创建MonoState类的实例和创建普通类的实例是一致的(通过new()).这减少了沟通成本.
  2. 可派生性. MonoState的派生类也具有MonoState性的. 这主要是因为子类和父类共享相同的static数据域. MonoState的继承, 可以看做是基于相同数据下的行为多态性的派生.

当派生类也需要具有单实例特性时,MonoState模式的优势是巨大的,MonoState子类天生就是MonoState的.
当然,MonoState模式也是有争议的,最大的争议当属static数据域的恰当性. 全局static数据,是导致不少程序Bug的源头. 其次由于静态数据是单个JVM作用域内的,所以它是不可跨JVM的.

当我们需要单实例特性时,如果知会使用者要使用Instance而非new来获取实例不会造成麻烦,那么Singleton模式会是首选. 而当需要保证MonoState是可继承时,使用MonoState模式是不错的选择.

最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 137,297评论 19赞 139
  • 前言 本文主要参考 那些年,我们一起写过的“单例模式”。 何为单例模式? 顾名思义,单例模式就是保证一个类仅有一个...
    tandeneck阅读 2,692评论 1赞 8
  • 1 场景问题# 1.1 读取配置文件的内容## 考虑这样一个应用,读取配置文件的内容。 很多应用项目,都有与应用相...
    七寸知架构阅读 7,065评论 12赞 68
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 35,398评论 18赞 399
  • 从三月份找实习到现在,面了一些公司,挂了不少,但最终还是拿到小米、百度、阿里、京东、新浪、CVTE、乐视家的研发岗...
    时芥蓝阅读 43,060评论 11赞 349

友情链接更多精彩内容