保持对象的单一性 - singleton 和 monostate

        很多时候,我们需要一些特殊的类,这些类因为资源等原因而只能有一个实例,实现这样目的的方式可能有很多,而这里要说的两个模式,通过其表达方式的有效性,能给我们带来很好的“代价/收益”平衡。 记得在Robert Martin的经典作品:敏捷软件开发-原则、模式与实践 中,这两个模式也是被单独提出来的。
       1. Singleton
       这个大概是学习设计模式时最先能够掌握和应用的一个模式,中文也常称为单件模式,其设计虽然简单,却具有很强的表达力。像我们在连接数据库时,不希望每次都打开一个新的连接,这个时候就可以用Singleton来设计这个连接,每次都通过Singleton来得到一个相同的连接(当然,singleton也可以扩展为提供n个实例,这就相当于一个连接池了)。
       Singleton的实现很简单,其提供一个公有的静态方法去访问Singleton实例,而将构造函数用private屏蔽,如下面代码所示:
public   class  Singleton
{
     
private static Singleton instance = null;      //Singleton 的实例
     
     
private Singleton () {}                                 //用private屏蔽掉构造函数

     
public static Singleton getInstance()    
//这个函数用来得到Singleton的实例
     
{
           
if (instance == null)
                instance 
= new Singleton();
           
return instance;
      }

}

       2. Monostate
       singleton非常好的完成了对单个实例的限制,但是使用如Singleton.getInstance()这样的方法时,使用者就知道这是个单件,也就是说singleton对于客户(这里的客户是指使用singleton的代码)来说是不透明的。而monostate的表现恰恰和singleton相反,其对于不同的实例,使用起来却像同一个对象。
       如何实现这样的效果呢,singleton中构造函数是私有的(private),monostate因为要创建不同实例,构造函数必须是public,我们只需再将getInstance从静态函数变为非静态的即可。这是代码示例:      
public   class  Monostate
{
    
private static int a = 0;  //需要使用单一实例的对象(这里是个int的整数)

    
public Monostate () {}  //这里是公有的构造函数了

    
public int getA()
    
{
          
return a;
     }

    
    
public void setA( int a ) //如果需要对其设值,可以加上set函数
    {
          
this.a=a;
     }

}
       可以看到,monostate实际上就是用成员函数来操作静态变量,而这种使用是对于客户透明的。而在实际的使用中,调用方式也会不一样,如:
public   void  test()
{
     Singleton s1 
= Singleton.getInstance();    //得到Singleton的实例  (注意,我们没有用 new)
     Singleton s2 = Singleton.getInstance();  //再次得到Singleton的实例
     assertSame(s1,s2);                                 //这两个是一样的
     
     Monostate m1 
= new Monostate();         //new 一个Monostate
     Monostate m2 = new Monostate();         //new 另一个Monostate
     
     m1.setA(
5); 
     System.out.println(m2.getA());                 
//这里的结果是打出5
}

       Singleton和Monostate的区别:
       可以从他们的实现上看到,虽然singleton和monostate都是为了保持对象的单一性,但是前者则是在结构上限制单一性,而后者则是从行为上强制其单一性,并没有对结构进行限制,也正是因为这样,monostate对于客户透明而singleton则不行。 在实际的使用中,我们需要根据实际情况决定使用什么样的机制,除去前面所说的透明性,平台和资源占用也是进行选择的因素,monostate是不可以跨多个平台使用的,而singleton则可以通过如RMI等合适的中间件进行跨平台或跨虚拟机使用;同时,和singleton用getInstance返回同一个对象不同的是,monostate创建时是new出来的一个个对象,而这些对象的创建和回收都会占用资源;再者,singleton没有使用时是不创建对象的,而monostate则肯定为其对象申请内存。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值