面向对象程序的设计方式-单例方式

单利模式的核心点在于只能生成1个对象,并且是由类中的静态变量保存。

以下代码来自《深入PHP 面向对象、模式与实践》(第三版)第9章

/**
 * Created by PhpStorm.
 * User: Eilen
 * Date: 2018/8/31
 * Time: 22:48
 */

class Preferences
{
    private $props = array();
    private static $instance;

    private function __construct(){}

    /**
     * 获取单例模式对象
     * @return mixed
     */
    public static function getInstance()
    {
        if (empty(self::$instance)){
            self::$instance = new Preferences();
        }
        return self::$instance;
    }

    /**
     * 接收对象的参数,并且赋值
     * @param $key
     * @param $val
     */
    public function setProperty($key, $val)
    {
        $this->props[$key] = $val;
    }

    public function getProperty($key)
    {
        return $this->props[$key];
    }
}

//引用单例模式

$pref = Preferences::getInstance();
$pref->setProperty('name', 'matt');

unset($pref);

$pref2 = Preferences::getInstance();
print $pref2->getProperty('name');

定义

  单例方式(Singleton Pattern)是最不难易行的一种设计情势。
  英文原话是:Ensure a class has only one instance,and provide a
global point of access to it.
  意思是:确保一个类唯有一个实例,而且自动实例化并向整个系统提供这些实例。

  单例形式的主要意义是确保一个类只有一个实例存在。单例情势可以用在建立目录,数据库连接等须求单线程操作的场合,用于落到实处对系统资源的决定。

单例情势的缺点

  1.单例格局不可以创造子类,且扩张困难。若要扩张,除了修改代码以外基本上并未第三种途径得以兑现。
  2.单例格局对测试不利。在竞相开发条件中,如果使用单例情势的类没有马到成功,程序是不可能进行测试的;单例方式的类一般不会兑现接口,那也妨碍了选取mock的法子虚拟一个对象。
  3.单例形式与单一职责规范有冲突。一个类应该只兑现一个逻辑,而不爱惜它是或不是是单例的,是还是不是利用单例情势取决于环境,单例形式。

  饿汉式单例类

  饿汉式代码如下:

public class Singleton{
    private static Singleton m_instance = new Singleton();
    //构造方法私有,保证外界无法直接实例化
    private Singleton(){
    }
    //通过该方法获得实例对象
    public static Singleton getInstance(){
        return m_instance;
    }        
}

     
下边那段代码中,在类加载时,静态变量m_instance会被开端化,此时类的私房构造函数会被调用,单例类的绝无仅有实例就被创建出来。单例类中最要害的特性是类的构造函数是个体的,从而防止外界利用构造函数直接开立出任意多的实例。别的,构造函数是私有的,因而该类不可以被持续。

  懒汉式单例类

  懒汉式单例类与饿汉式单例类相同的是,类的构造函数是个体的;区其他是,懒汉式单例类在加载时不会将团结实例化,而是在第一遍被调用时将自己实例化。

  懒汉式代码如下:

 

public class Singleton{
    private static Singleton _instance = null;
    //构造方法私有,保证外界无法直接实例化
    private Singleton(){
    }    
    //方法同步
    synchronized public static Singleton getInstance(){
        if(_instance==null){
            _instance = new  Singleton();
        }
        return _instance;
    }
}

  上面那段代码中,懒汉式单例类中对静态方法getInstance()举行联合,以有限帮忙八线程环境下只成立一个实例。例如:假如getInstance()方法未被联合,并且线程A和线程B同时调用此办法,则履行if(_instance==null)语句时都为真,线程A和线程B会分别创造一个目的,在内存中就会并发多个目的,那样就违背了单例方式;单运用synchronized关键字展开协同后,就不会油然则生这种意况了。

  饿汉式单例类与懒汉式单例类之间的区别

  1.懒汉式单例类在被加载时实例化,而懒汉式单例类在首先次引用时实例化。
  2.从资源利用上说,饿汉式单例类比懒汉式单例类要差一点(因为饿汉式一开头就会实例化一个目的占用系统资源),但从速度和反应时间角度来讲,则饿汉式单例类比懒汉式单例类好一些。

  3.饿汉式单例类可以在Java中贯彻,但不易在C++中落到实处。GoF在提议单利格局的概念是举的事例是懒汉式的,他们的书影响较大,以至于Java中单例类的例子大多是懒汉式的。实际上,饿汉式单例类更契合Java语言本身的特色。

设计形式-单例格局(02),设计形式例形式02

单例方式的使用情况

  在一个种类中,如果须求一个类有且仅有一个实例,当出现三个实例时就会招致不良反应,则此时得以动用单例方式。典型气象如下:

  1.须求扭转唯一体系号的条件。
  2.在全体项目中必要一个访问点或共享数据。(如web页面上的计数器)
  3.成立一个对象须要开支的资源过多,如访问IO和数据库等资源。
  4.亟需定义多量的静态常量和静态方法(如工具类)的条件,可以行使单例格局。

那是一个误导人的线程例子,经过修改后.就变得很不难.

public class CounterSingleton {
    //懒汉式加载
    private static CounterSingleton singleton = new CounterSingleton();
    //私有构造,防止生成对象
    private CounterSingleton() {
    }
    //获取类
    public static CounterSingleton getInstance() {
        return singleton;
    }
    //对象的私有变量
    public int count = 0;
    //懒汉式对象的方法
    public synchronized void inc() {        
        //加访问量
        count++;
        //System.out.println(count);
    }

      public int getCount() {
        return count;
      }

}

public class Counter {
    public static void main(String[] args) {
        long time_s=System.currentTimeMillis();
        //同时启动1000个线程,去进行i++计算,看看实际结果
        for (int i = 0; i < 1000; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    CounterSingleton.getInstance().inc();
                }
            }).start();
        }

        //这里每次运行的值都有可能不同,显示结果可能不为1000(inc方法没有sychonized的话,count就是真的不是1000了)
        System.out.println("运行结果:CounterSingleton.count=" + CounterSingleton.getInstance().getCount());
        System.out.println("耗时:"+(System.currentTimeMillis()-time_s));
    }
}

源码

http://www.bkjia.com/Javabc/1232484.htmlwww.bkjia.comtruehttp://www.bkjia.com/Javabc/1232484.htmlTechArticle设计模式-单例模式(02),设计模式例模式02 定义
单例方式(Singleton Pattern)是最简单易行的一种设计情势。 英文原话是:Ensure
a class has only one…

单例对象的助益

  1.由于单例形式在内存中只有一个实例,裁减了内存的开支,越发是当一个目的急需反复地被创立、销毁而且成立或销毁的性质又惊慌失措优化时,单例方式的优势就非常鲜明。
  2.由于单例格局值生成一个实例,所以裁减了系统的特性用度,当一个目标的发出须求相比较多的资源时,如读取配置文件、暴发其余信赖对象时,可以在启动时间接发生一个单例对象,然后永久驻留内存的法子来缓解。
  3.单例形式能够幸免对资源的一连串占用。例如:一个写文件动作,由于唯有一个实例存在于内存中,幸免了对同一个资源文件的还要写操作。
    4.单例情势可以在系统装置全局访问点,优化和共享资源访问。

分类

  Java语言的性状使得在Java中落到实处单例情势日常有两种表现格局:

  饿汉式单例类:类加载时,就进展对象实例化。
  懒汉式单例类:首回引用类时,才进行对象实例化。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图