设计模式-单例模式(一)

来源:互联网 发布:启凡网络是培训机构 编辑:程序博客网 时间:2024/05/21 16:08

单例模式(一)

特别声明:由于本人也为初学者,如果以下讲解的有问题,望大家可以批评指正,欢迎一起来讨论。

定义:确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,它提供全局访问的方法。

由定义可以看出,单例模式必须要满足如下几点:

(1)系统中一个类只能有一个实例;

(2)自行实例化;

(3)提供全局访问的方法。

既然单例模式符合上边三种规则,那在实现这三种规则时,具体是咱们实现的呢?首先看一下以下最简单的单例模式的实现:

public class BaseSingle {private static BaseSingle instance=null;private BaseSingle(){}public static BaseSingle getInstance() {if(instance==null){instance=new BaseSingle();}return instance;}}
看到以上代码,大家也许会有这几个问题:

(1)代码中的成员变量为什么要声明为静态的?

(2)类的构造函数为什么要声明为私有的?

(3)得到实例的getInstance方法为什么要声明为静态的呢?

想弄清这几个问题,我想应该从单例模式的特点开始思考:

(1)系统中一个类只能有一个实例:java中,一般我们在创建类的实例时,都是在类的外部new出对象,如:如 A a=new A();这样,我们就给类A创建了一个实例a,可是,如果在写程序时,我们可以在类的外部任意调用其构造函数进行类的实例化,那还怎么能满足系统中一个类只能有一个实例这个特点呢?so,为了禁止客户端自己在类外部进行实例化,只能让客户端无法访问其类的构造函数,so,将类的构造函数声明为私有成员,及类的实例只能在类中进行创建。

写到这我想大家会又有问题了,我们在访问一个类中的成员变量或者方法时,都是先得到这个类的实例,然后通过这个类的实例来访问其中类的成员变量或者方法,可是,你为了保证客户端不能随意的创建对象,将其构造函数进行了私有化,那外部想要访问这个类中的成员变量或其中的方法,该怎么访问呢?既然不能new出对象来访问了,我想就只能另找途径了。想到这里,大家应该会想到java中访问类中的成员变量或方法常用有以下两种方式:

1)通过new出一个对象,然后通过对象进行其成员变量或成员方法的访问(此方法已在前述中被证明不可行);

2)通过类名直接访问其静态方法或静态变量,以达到访问该类中成员变量或其方法的目的..

注意:这两种方式虽然表面都可以访问类中的变量或者类中的函数,可其实现原理,内存分配是完全不一样的。

既然第一种方法不行,那就只能想,不用创建对象,就可以访问类中的变量或函数,那这自然的就让我们想到使用类名加静态方法或静态变量访问其成员了,再加其前边我们将类的构造函数声明为私有成员,及只能在类的内部进行类的实例化,so,我们只能在类的内部声明一个静态的类的对象等待我们去访问,于是static BaseSingle instance=null便自然而然地出现在我们面前,可是为了实现对类内部成员变量的保护,我们一般都讲类中的变量变为私有的,可是,变成私有之后,我们又该怎么取访问呢?没错,只能通过声明一个公有的方法,通过该方法的返回值访问该变量,可是,该方法必须保证可以在客户端不创建类的对象的情况下就可以访问到,于是,我们自然地也想到将其声明为静态的公有的方法,通过该方法将类中的类实例返回,于是getInstance()为何要声明为静态公有的方法,以及方法中为何加上if语句判断,到这就已经清楚了。到这也满足了单例模式定义中的第二个特点,自行实例化 。

(2)提供全局的方法,static修饰的静态变量或方法是在加载类时进行创建的,整个过程中只初始化一次,通过全局只存在一个的变量进行对应的方法访问,于是保证了提供全局方法的特性。

至此,将上述简单的单例模式的代码实现进行了讲解。

可是,再仔细想一下,代码这样写的话,如果只是一个用户访问,我们可以保证其单例,当多线程并发访问时,是不是也能保证其单例性呢?大家可以先思考一下,然后带着问题看即将发表的 单例模式(二)

0 0
原创粉丝点击