zoukankan      html  css  js  c++  java
  • (@WhiteTaken)设计模式学习——单例模式

    单例模式,个人理解就是,使用了这个模式,可以保证一个类只生成唯一的实例对象。就是在整个程序中,这个类只存在一个实例对象。

    GoF对单例模式的定义:保证一个类,只有一个实例存在,同时提供能对该实例加以访问的全局访问方法。

    客户端的代码用来测试,获取到的实例只有一个。直接上代码。

     1 public class MainClass {
     2     public static void main(String[] args) {
     3         Person person1=Person.getPerson();//获取Person对象
     4         Person person2=Person.getPerson();//获取Person对象
     5         person1.setName("Tom");
     6         person2.setName("WhiteTaken");//如果两个获取的到的对象的实例,是同一实例,那么打印出来的名字应该是一样的。
     7         System.out.println(person1.getName());
     8         System.out.println(person2.getName());
     9     }
    10 }

    如果不是单例模式,而仅仅是创建了几个对象 ,那么两次打印的结果,将会是两个不同的名字。

    而单例模式的情况,获取的到的是同一个对象,那么两次打印的结果,将是第二次赋值的结果。

    单例测试结果如下。

    好,上面是测试结果,那么单例模式是怎么实现的呢。

    我学习到的三种单例模式的创建方法。

    1.直接用final方式创建。只要类执行,就会创建这样一个对象。

    代码如下。

     1 public class Person {
     2     private String name;
     3     public static final Person perSon= new Person();//注意此处的final
     4     public String getName() {
     5         return name;
     6     }
     7 
     8     public void setName(String name) {
     9         this.name = name;
    10     }
    11     //构造函数私有化
    12     private Person(){
    13         
    14     }
    15     //获取对象的方法,final实现
    16     public static Person getPerson(){
    17         return perSon;
    18     }
    19 }

    通过final关键字,保证perSon只被赋值一次,即值生成一次对象。

    2.第二种方式,通过在获取对象的方法中判断person是否为null,如果不存在,则实例化person,如果存在,则直接返回person实例。

     1 public class Person2 {
     2     private String name;
     3     private static Person2 perSon;
     4     public String getName() {
     5         return name;
     6     }
     7     public void setName(String name) {
     8         this.name = name;
     9     }
    10     //构造函数私有化
    11     private Person2(){
    12         
    13     }
    14     //获取对象的方法,单线程模式可用
    15     public static Person2 getPerson(){
    16         if(perSon==null){
    17             return perSon=new Person2();
    18         }
    19         return perSon;
    20     }
    21 }

    以上方法是实现单例模式的第二种方法,但是此种方法有一个天然的劣势,就是只适合单线程开发。

    多线程的话,如果两个线程同时访问这个方法的话,返回的person对象可能会出现不一样的情况 ,那就不是单例了。

    如果使用同步方法的话(synchronized),多线程的情况下会造成线程等待,影响效率。

    3.第三种方式是通过双重检查的方式实现单例。

    双重判断,通过两次判断null,能够确保在多线程下,只生成一个单例。

     1 public class Person4 {
     2     private String name;
     3     private static Person4 perSon;
     4     public String getName() {
     5         return name;
     6     }
     7 
     8     public void setName(String name) {
     9         this.name = name;
    10     }
    11     //构造函数私有化
    12     private Person4(){
    13         
    14     }
    15     //获取对象的方法,双重检查
    16     public static  Person4 getPerson(){
    17         if(perSon==null){
    18             synchronized (Person4.class) {
    19                 if(perSon==null){
    20                     return perSon=new Person4();
    21                 }                
    22             }
    23         }
    24         return perSon;
    25     }
    26 }

    这样就完成单例模式的简单应用。

    要想达到学以致用,真的很难,工作久了,很多东西都忘了。。。单例模式写的一个小例子,加强理解。

    需要注意:只创建了一次对象。

     1  class Program
     2     {
     3         static void Main(string[] args)
     4         {
     5             Console.WriteLine("================测试单例模式=========begin======");
     6             Test tst = GetAllTest.GetTest();
     7             tst.TestPrint();
     8             Test tst2 = GetAllTest.GetTest();
     9             tst2.TestPrint();
    10             Console.WriteLine("================测试单例模式=========end========");
    11             Console.Read();
    12         }
    13     }
    14 
    15 
    16     class Test
    17     {
    18         public Test(){}
    19         public void TestPrint()
    20         {
    21             Console.WriteLine("单例模式打印结果");
    22         }
    23     }
    24 
    25     class GetAllTest
    26     {
    27         private static Test ts;
    28         public static Test GetTest()
    29         {
    30             if(ts == null)
    31             {
    32                 Console.WriteLine("创建Test对象过程");
    33                 ts = new Test();
    34             }
    35 
    36             return ts;
    37         }
    38     }

    打印结果:

    好好努力,提高自己!!!

  • 相关阅读:
    判断js中的类型
    js数组的4种遍历方式
    js笔记
    Windows 常用 CMD 命令介绍
    css笔记
    winform项目笔记:
    Angular4 中内置指令的基本用法
    Angular4入门笔记
    8、跳台阶
    7、斐波那契数列
  • 原文地址:https://www.cnblogs.com/WhiteTaken/p/6384726.html
Copyright © 2011-2022 走看看