设计模式学习系列——单例模式

单例模式

  单例模式(Singleton Pattern),在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中,应用该模式的类一个类只有一个实例。即一个类只有一个对象实例。

  优点:1)在内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例(比如首页页面缓存)。 2)避免对资源的多重占用(比如写文件操作)。

  缺点:违背了“单一职责原则”,该类既是工厂又是产品(自己创建了自己);

  从具体实现角度来说,就是以下三点:

    一是单例模式的类只提供私有的构造函数,

    二是类定义中含有一个该类的静态私有对象,

    三是该类提供了一个静态的公有的函数用于创建或获取它本身的静态私有对象。

  考虑以下场景,共享单车现在只有一辆,Jack和Mary都想使用。 这就用到了单例模式。

  使用内部静态类的方法创建,这种方法既保证了实例在第一次使用的时候创建,也保证了线程安全。参考php代码:

<?php
/*
 * 单例模式示例
 */
error_reporting(E_ALL);
ini_set(‘display_errors‘,‘on‘);

    //
    class SingletonBike{
        private static $instance = null; //创建静态私有的变量保存该类对象
        private $ownerUser = "";//使用者姓名

        //构造函数私有化,防止直接创建对象
        private function __construct($ownerUser) {
             $this ->ownerUser = $ownerUser;
        }
        //构造函数私有化,防止直接创建对象

       //防止克隆对象
        private function __clone() {
        }
        //静态方法,创建实例
        public static function getInstance($ownerUser){
            if(!self::$instance instanceof self){//self指类,this代表实例,这里指代静态属性,使用self
                self::$instance = new self($ownerUser);
                return self::$instance;
            }
            if(self::$instance->ownerUser == ""){
                self::$instance->ownerUser = $ownerUser;
                return self::$instance;
            }else{
                return null;
            }
        }
        public function getOwnerUser(){
            return $this->ownerUser;
        }
        //静态方法,销毁实例
        public static function destroyInstance(){
            //self::__destruct();
            self::$instance->ownerUser = "";
        }
    }

    $singletonBike = SingletonBike::getInstance("Mary");
    echo $singletonBike->getOwnerUser()."<br/>";//Mary
    $singletonBike2 = SingletonBike::getInstance("Jack");
    var_dump($singletonBike2);//null
    echo "<br/>";
    SingletonBike::destroyInstance();
    $singletonBike2 = SingletonBike::getInstance("Jack");
    var_dump($singletonBike2);//object(SingletonBike)#1 (1) { ["ownerUser":"SingletonBike":private]=> string(4) "Jack" }
    echo "<br/>";
    echo $singletonBike->getOwnerUser()."<br/>";//Jack

?>

Mary使用后,Jack不能使用。必须等到Mary不用以后,Jack才可以使用。

另一个版本,可以直接销毁单例创建的实例,节省内存,更优。如下:

<?php
/*
 * 单例模式示例
 */
error_reporting(E_ALL);
ini_set(‘display_errors‘,‘on‘);

    //
    class SingletonBike{
        private static $instance = null; //创建静态私有的变量保存该类对象
        private $ownerUser = "";//使用者姓名

        //构造函数私有化,防止直接创建对象
        private function __construct($ownerUser) {
             $this ->ownerUser = $ownerUser;
        }
        //构造函数私有化,防止直接创建对象

       //防止克隆对象
        private function __clone() {
        }
        //静态方法,创建实例
        public static function getInstance($ownerUser){
            if(!self::$instance instanceof self){//self指类,this代表实例,这里指代静态属性,使用self
                self::$instance = new self($ownerUser);
                return self::$instance;
            }else{
                return null;
            }
        }
        public function getOwnerUser(){
            return $this->ownerUser;
        }
        //静态方法,销毁实例
        public static function destroyInstance(&$instance){
            self::$instance = null;
            $instance = null;
        }
    }

    $singletonBike = SingletonBike::getInstance("Mary");
    echo $singletonBike->getOwnerUser()."<br/>";//Mary
    $singletonBike2 = SingletonBike::getInstance("Jack");
    var_dump($singletonBike2);//null
    echo "<br/>";
    SingletonBike::destroyInstance($singletonBike);
    $singletonBike2 = SingletonBike::getInstance("Jack");
    var_dump($singletonBike2);//object(SingletonBike)#1 (1) { ["ownerUser":"SingletonBike":private]=> string(4) "Jack" }
    echo "<br/>";
    var_dump($singletonBike);//为空
?>

js版本如下:

<!DOCTYPE html>
<html>
    <head>
        <title>单例模式示例</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <script>
            var SingletonBikeController = (function(){//采用闭包来实现,因为有私有变量啊
                this.instance = null;

                this.SingleBike = function(ownerUser){
                    this.ownerUser = ownerUser;
                    this.getOwnerUser = function(){
                        return this.ownerUser;
                    }
                }
                return {//暴露的公共静态方法
                    "getInstance":function(ownerUser){
                        if(this.instance == null){
                            this.instance = new SingleBike(ownerUser);
                        }
                         return this.instance;
                    },
                    "destroyInstance":function(instance){
                        this.instance = null;
                        instance.ownerUser = "";
                    }
                }
            })();

            var singletonBike = SingletonBikeController.getInstance("Mary");
            console.log(singletonBike.getOwnerUser());//mary
            singletonBike2 = SingletonBikeController.getInstance("Jack");
            console.log(singletonBike2.getOwnerUser());//mary
            SingletonBikeController.destroyInstance(singletonBike);
            console.log(singletonBike.getOwnerUser());//""
            singletonBike2 = SingletonBikeController.getInstance("Jack");
            console.log(singletonBike2.getOwnerUser());//jack

        </script>
    </head>
</html>

参考文献:

单例模式

设计模式-——单例模式  

原文地址:https://www.cnblogs.com/Andres/p/8892349.html

时间: 2024-10-08 17:02:38

设计模式学习系列——单例模式的相关文章

【我的设计模式学习】单例模式

单例模式大概是最直观的一种设计模式了.尽管直观却不简单. 数学与逻辑学中,singleton定义为"有且仅有一个元素的集合".单例模式可以如下定义:"一个类有且仅有一个实例,并且自行实例化向整个系统提供". 我比较喜欢Design Patterns 一书中的描述"保证一个类仅有一个实例,并提供一个访问它的全局访问点". 单例模式的特点 1.单例类只能有一个实例. 2.单例类必须自己自己创建自己的唯一实例. 3.单例类必须给所有其他对象提供这一实例

设计模式学习01—单例模式

一.动机与定义 系统中有些资源只能有一个,或者一个就够,多个浪费.例如一个系统只能有一个窗口管理器或文件系统.一个系统只能有一个计时器或序号生成器.web系统只能有一个页面计数器等等.此时,最好就需要把这些资源设置成有且仅有一个实例. 代码中也就是如何保证一个类只有一个实例并且这个实例能够被访问呢?只有一个实例的就意味着不能让其他类来实例化,也就是只能自己实例化自己.能够被访问也就意味着自身要对外提供全局方法来获取到这个实例,这就是单例模式. 单例模式定义:确保某一个类只有一个实例,而且自行实例

Java设计模式学习01——单例模式(转)

原地址:http://blog.csdn.net/xu__cg/article/details/70182988 Java单例模式是一种常见且较为简单的设计模式.单例模式,顾名思义一个类仅能有一个实例,并且向整个系统提供这一个实例. 单例模式的特点: 单例类仅能有一个实例. 单例类必须为自己创建实例. 单例类必须向外界提供获取实例的方法. 以下是几种实现方法 一.懒汉式单例(能够延时加载) public class SingleTon { private static SingleTon ins

C#设计模式学习笔记-单例模式

最近在学设计模式,学到创建型模式的时候,碰到单例模式(或叫单件模式),现在整理一下笔记. 在<Design Patterns:Elements of Resuable Object-Oriented Software>中的定义是:Ensure a class only has one instance,and provide a global point of access to.它的主要特点不是根据客户程序调用生成一个新的实例,而是控制某个类型的实例数量-唯一一个.(<设计模式-基于C

【C++深入浅出】设计模式学习之单例模式

但凡成为大家公认的模式,都是有一些不可小觑的威力,今天分享一个简单的设计模式:单例模式. 单例模式用于一些只希望有一个实例的类或者只希望执行一次的操作:校长只能有一个.老板只能有一个.用户点击弹窗只希望弹出一次.用全局变量等方式也可以实现,但是多了很多判断和处理代码,并且职责模糊,类的唯一实例化是交给调用者进行判断处理的,每调用一次就要做一次判断,重复了很多工作量,如果是多线程编程,不好的同步设计更是会导致程序卡顿. 如果还在为这些重复工作苦恼,是时候着手单例模式了:设计简单.调用方便.一劳永逸

Java设计模式学习记录-单例模式

前言 已经介绍和学习了两个创建型模式了,今天来学习一下另一个非常常见的创建型模式,单例模式. 单例模式也被称为单件模式(或单体模式),主要作用是控制某个类型的实例数量是一个,而且只有一个. 单例模式 单例模式的实现方式 实现单例模式的方式有很多种,大体上可以划分为如下两种. 外部方式 在使用某些全局对象时,做一些“try-Use”的工作.就是如果要使用的这个全局对象不存在,就自己创建一个,把它放到全局的位置上:如果本来就有,则直接拿来使用. 内部实现方式 类型自己控制正常实例的数量,无论客户程序

设计模式学习之单例模式

一.单例模式实现方式 常见的 1.饿汉方式 示例代码: package com.mt.singleton;/** * 设计模式单例模式之饿汉实现方式 * 线程安全,调用效率高,但无法实现延迟加载 * @author MT * */public class SingletonDemo1 { private static SingletonDemo1 s = new SingletonDemo1(); //私有化构造器 private SingletonDemo1(){   } //添加获取对象的公

设计模式学习 之 单例模式

单例模式: 定义 一个类有且仅有一个实例,并且自行实例化向整个系统提供. <来自百科> 这些 概念和要点 是 了解 单例模式的 一些基本概念 C# 单例实现要点 Singleton模式是限制而不是改进类的创建. Singleton类中的实例构造器可以设置为Protected以允许子类派生. Singleton模式一般不要支持Icloneable接口,因为这可能导致多个对象实例,与Singleton模式的初衷违背. Singleton模式一般不要支持序列化,这也有可能导致多个对象实例,这也与Si

php设计模式学习(单例模式和观察者模式)

1.单例模式 前几天跟一个朋友讨论的时候,朋友提了一个问题,为什么所有类不都用单例模式,都用单例模式真的是最好的吗? php中不管是new出来的对象还是静态变量,只对本次请求有效,当一次请求结束的时候,所有的对象和变量都会被销毁. 当一个对象每次请求只用一次的时候,单例模式和直接new没什么区别吧. 另一点,当一个对象涉及较多的属性修改或设置,又需要多次使用,很多时候可能我们更希望每次都进行初始化,而不是直接使用一个不知道被做了哪些操作的对象 综上,个人认为,单例模式更适用于一次请求需要多次使用