• OO模式-Singleton


    讨论一:

    既然仅仅有一个类?为什么非要用一个模式来定义?难道就不能用程序猿之间的约定又或者使用伟大的设计模式来完毕?

    1)先来说说全局变量的优点,当定义一个全局变量时,不论什么一个函数或者一行代码都能够轻松訪问全部的全局变量,而且不用付出额外的代价,轻松简便。

    就如在敲机房收费的时候,我就定义机房登陆username为一个全局变量,由于在整个系统的运行过程中,非常多方面都用到了username的信息。在此。调用全局变量。轻而易举就解决,非常是方便。可是假设换成一个大型软件,又或者你的整个系统中定义了非常多全局变量,这个时候使用起来就会比較混乱,使原本简单的事情变得复杂化了。

    2)对于变量名的设定我认为也是一个难题,假设过多的话真的会导致变量名的冲突,到时候无疑又给自己添加了一个难题。

    3)当然最重要的一点,定义全局变量,无疑添加了模块与函数之间的耦合度。也就是说你已经把他们牢牢的拴在了一起,想要再又一次改动,可就变得不是那么简单了。

    来看看类图:


    getInstance()方法是静态的,这意味着它是一个类方法,所以能够在代码的不论什么地方使用,事实上这和全局变量使用起来是一样的,只是单件能够延迟实例化。

    讨论二:

    单例模式的使用之处:

    有一些对象我们仅仅使用一个。如threadpoolCache。对话框,注冊表对象,日志对象。充当打印机、显卡等设备的驱动程序的对象。

     

    讨论三:简单而又不简单

    简单之意:由于它仅仅涉及到了一个类,所以终于“祸害”了大家,事实上他是非常调皮的!只是调皮归调皮,却还是蛮厉害的。

    事实上自己对于Chocolate还是蛮钟情的。假设自己可以开一个制造巧克力的工厂多好。这样既能用到自己所学的知识,还能满足自己的小胃口。只是这样的甜食依然还是少吃为好吧!

    假如我们这有一个锅炉正在工作,而不知情的工作者又打开了一个锅炉。本来一个锅炉的原料就已经足够,再加一个。可想而知。会有多少浪费……

    这时候我们就能够使用"Singleton"来帮你解决这个问题:

    避免不知情的情况下再次打开一个锅炉。也就是把锅炉设计单件:

    //巧克力制作一个单一的过程
    public class ChocolateBoiler {
      private boolean empty;  //定义私有变量
      private boolean boiled;
      //uniqueInstance持有唯一的单件实例
      private static ChocolateBoiler uniqueInstance;
     
      private ChocolateBoiler(){
      //開始时。锅炉是空的
      empty=true;
      boiled=true;
    }
    public static  ChocolateBoiler getInstance()
    {
      if (uniqueInstance==null){
      //System.out.println("Creating unique Instance of Chocolate Boiler");
      uniqueInstance = new ChocolateBoiler();
    }
      return uniqueInstance;
    }
     
    public void fill() <span style="font-family: 华文新魏; font-size: 16pt; text-indent: 21pt;">{</span>
      if (isEmpty()) {
        empty = false;
        boiled = false;
        //填充混合物
        }
    }
    

    但是运行完之后会发现。自己同意在加热的过程中继续增加原料,这但是会溢出的啊。我们唯一想到的原因就是刚刚使用的多线程对ChocolateBoiler进行了优化,来建立一个ChocolateCotroller来控制一下吧!

    public class ChocolateController
    {
    public static void main(String args [])
    {
     ChocolateBoiler boiler = ChocolateBoiler.getInstance();
     boiler.fill();   //填充
     boiler.boil();<span style="white-space:pre">	</span> //煮沸方法
     boiler.drain();  //排除煮沸的填充物的方法
     
     // will return the existing instance
     ChocolateBoiler boiler2= ChocolateBoiler.getInstance();
    }
    

    假设boiler在工作。那么boiler2仅仅会听后指挥。

    对于多线程的处理採用synchronized方法。也就是把getInstance()方法变成同步(synchronized)方法,多线程灾难轻而易举的就攻克了。

    //多线程处理
    public static synchronized ChocolateBoiler getInstance()
    {
      if (uniqueInstance==null){
      uniqueInstance = new ChocolateBoiler();
    }
      return uniqueInstance;
    }
    

    假设想在不改变运行效率的情况下。急切的创建实例,能够在一个静态初始化器创建单件,

    Public class Singleton ChocolateBoiler
     {
      //在static initializer中创建单件,保证了线程安全
      Private static ChocolateBoiler  uniqueInstance = new ChocolateBoiler();  
     
         Private  ChocolateBoiler() {}
     
         Public static ChocolateBoiler getInstance()
         {
          Return uniqueInstance;   //直接使用
         }
     }


    对于Singleton也仅仅是懂得了一个皮毛而已。非常期待在机房合作的时候实践一番!唠叨了半天,事实上就是三种对于巧克力锅炉代码多遇到的问题:

    1)同步getInstance方法,保证可行的最直接的方法

    2)急切实例化

    3)双重检查枷锁()

    三种方法是一个层层优化的过程,只是优化也要针对问题,对症下药才可。






  • 相关阅读:
    使用jedis连接redis
    布隆过滤器redis缓存
    SQL与NOSQL
    Charles 移动端抓包工具,使用方法以及注意事项
    安装npm包的时候报错rollbackFailedOptional: verb npm-session
    You may need an appropriate loader to handle this file type.
    数组去重
    判断两个数组是否相等(包括数组里边的键值对是否相等)
    数组里的字符串转为数字
    背景色铺满整个屏幕
  • 原文地址:https://www.cnblogs.com/blfbuaa/p/6692258.html
Copyright © 2020-2023  润新知