`
lushuaiyin
  • 浏览: 673037 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

设计模式之二 --- Singleton 模式 .

 
阅读更多

【1】基本概念

Singleton 是一种创建性模式,它用来确保只产生一个实例,并提供一个访问它的全局访问点。对一些类来说,保证只有一个实例是很重要的,比如有的时候,数据库连接或 Socket 连接要受到一定的限制,必须保持同一时间只能有一个连接的存在。

【2】简单分析

我们先来看一下该设计模式的UML结构图:


为了实现 Singleton 模式,我们需要的是一个静态的变量,能够在不创建对象的情况下记忆是否已经产生过实例了。静态变量或静态方法都可以在不产生具体实例的情况下直接调用,这样的变量或方法不会因为类的实例化而有所改变。在上面的模式结构图中的 uniqueInstance 就是这个独立的静态变量,它可以记忆对象是否已经实例化了,在静态方法 getInstance() 中对这个变量进行判断,若没有实例化过就产生一个新的对象,如果已经实例化了则不再产生新的对象,仍然返回以前产生的实例。

【3】如何用java语言来实现该设计模式:以下采用2种方法来实现该模式。

第一种方法:用静态方法实现 Singleton 这种方法是使用静态方法来监视实例的创建。为了防止创建一个以上的实例,我们把构造器声明为 private。这样可以防止客户端程序员通过除由我们提供的方法之外的任意方式来创建一个实例。如果不把构造器声明为private,编译器则会创建一个默认的public的构造器。

具体实现的代码如下:

  1. <spanstyle="font-size:16px;">packagecom.andyidea.patterns.singleton;
  2. publicclassSingleton{
  3. privatestaticSingletons;
  4. /**
  5. *把构造函数设置为private
  6. */
  7. privateSingleton(){
  8. }
  9. /**
  10. *实例化对象的唯一接口
  11. *@return
  12. */
  13. publicstaticSingletongetInstance(){
  14. if(s==null){
  15. s=newSingleton();
  16. }
  17. returns;
  18. }
  19. }</span>
测试类代码如下:

  1. <spanstyle="font-size:16px;">packagecom.andyidea.patterns.client;
  2. importcom.andyidea.patterns.singleton.Singleton;
  3. /**
  4. *设计模式测试类
  5. *@authorAndy.Chen
  6. *
  7. */
  8. publicclassMainClient{
  9. publicstaticvoidmain(String[]args){
  10. Singletons1=Singleton.getInstance();
  11. Singletons2=Singleton.getInstance();
  12. System.out.println("WelcometoAndy.ChenBlog!"+"\n"
  13. +"SingletonPatterns."+"\n"
  14. +"-------------------------------");
  15. if(s1==s2)
  16. System.out.println("s1isthesameinstancewiths2");
  17. else
  18. System.out.println("s1isnotthesameinstancewiths2");
  19. }
  20. }</span>
程序运行的结果如下:

  1. WelcometoAndy.ChenBlog!
  2. SingletonPatterns.
  3. -------------------------------
  4. s1isthesameinstancewiths2
第二种方法:以静态变量为标志实现 Singleton 在类中嵌入一个静态变量做为标志,每次都在进入构造器的时候进行检查。问题在于构造器没有返回类型,如果确定创建一个实例成功与否.一个方法是调用一个函数来检查创建是否成功,然后简单的返回一个来自静态变量的值,但是这样做是不优雅的,而且容易发生错误。比较好的做法是创建一个当创建了一个以上的实例时可以抛出异常的类,这个类仅仅是调用父类方法,好处是用了自己创建的异常类型,错误信息更加清晰。

具体实现的代码如下:

  1. <spanstyle="font-size:16px;">packagecom.andyidea.patterns.singleton;
  2. publicclassSingleton{
  3. staticbooleaninstance_flag=false;
  4. publicSingleton(){
  5. if(instance_flag)
  6. thrownewSingletonException("Onlyoneinstanceallowed");
  7. else
  8. instance_flag=true;
  9. }
  10. }</span>
异常类代码如下:

  1. <spanstyle="font-size:16px;">packagecom.andyidea.patterns.singleton;
  2. /**
  3. *异常类
  4. *@authorAndy.Chen
  5. *
  6. */
  7. publicclassSingletonExceptionextendsRuntimeException{
  8. publicSingletonException(Stringexception){
  9. super(exception);
  10. }
  11. }</span>
测试类代码如下:

  1. <spanstyle="font-size:16px;">packagecom.andyidea.patterns.client;
  2. importcom.andyidea.patterns.singleton.Singleton;
  3. importcom.andyidea.patterns.singleton.SingletonException;
  4. /**
  5. *设计模式测试类
  6. *@authorAndy.Chen
  7. *
  8. */
  9. publicclassMainClient{
  10. publicstaticvoidmain(String[]args){
  11. System.out.println("WelcometoAndy.ChenBlog!"+"\n"
  12. +"SingletonPatterns."+"\n"
  13. +"-------------------------------");
  14. Singletons1,s2;
  15. //createoneincetance--thisshouldalwayswork
  16. System.out.println("Creatingoneinstance");
  17. try{
  18. s1=newSingleton();
  19. }catch(SingletonExceptione){
  20. System.out.println(e.getMessage());
  21. }
  22. //trytocreateanotherincetanced
  23. System.out.println("Creatingtwoinstance");
  24. try{
  25. s2=newSingleton();
  26. }catch(SingletonExceptione){
  27. System.out.println(e.getMessage());
  28. }
  29. }
  30. }</span>
运行结果如下:

  1. WelcometoAndy.ChenBlog!
  2. SingletonPatterns.
  3. -------------------------------
  4. Creatingoneinstance
  5. Creatingtwoinstance
  6. Onlyoneinstanceallowed
从输出的结果可以看出,第一个实例可以顺利创建,创建第二个实例的时候抛出了我们自定义的异常信息。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics