很多时候,我们需要一些特殊的类,这些类因为资源等原因而只能有一个实例,实现这样目的的方式可能有很多,而这里要说的两个模式,通过其表达方式的有效性,能给我们带来很好的“代价/收益”平衡。 记得在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则肯定为其对象申请内存。
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;
}
}
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则肯定为其对象申请内存。
本文介绍了两种设计模式:单例模式和独态模式。单例模式确保类只有一个实例,并提供了全局访问点。独态模式允许创建多个实例,但它们共享同一状态。

689

被折叠的 条评论
为什么被折叠?



