zoukankan      html  css  js  c++  java
  • 设计模式学习系列——单例模式

    单例模式

      单例模式(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
          
    ?>
    View Code

    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);//为空
    ?>
    View Code

    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>
    View Code

    参考文献:

    单例模式

    设计模式-——单例模式  

    JS是按值传递还是按引用传递?

    作者:Leven
    本博客主要记录个人工作和学习中的一些总结,经验和感悟。欢迎转载和评论,转载请给出原文链接。
    您也可以通过邮箱联系我:leven_developer#outlook.com
    如果文章对您有所帮助,您可以给我一点打赏,会让我更有动力做所从事的事情,非常感谢。
  • 相关阅读:
    ABP 数据库 -- ABP&EF中的多表、关联查询
    C# List集合基础操作
    C# ABP 允许跨域请求
    异或运算、与运算、或运算 运用在 多项选择题
    C# ABP 配置连接数据库&创建表
    C# ABP WebApi与Swagger UI的集成
    C# 深入了解泛型
    8、SpringBoot+Mybatis整合------参数取值方式
    7、SpringBoot+Mybatis整合------PageHelper简单分页
    6、SpringBoot+Mybatis整合------参数传递
  • 原文地址:https://www.cnblogs.com/Andres/p/8892349.html
Copyright © 2011-2022 走看看