• 设计模式之单例模式


    单例,顾名思义就是单个实例

     

    1、单例模式的优点

    • 单例模式只产生一个对象,减少了系统开销,当一个对象的产生需要的资源比较多时,如读取配置文件,产生其他依赖对象,则可以再其应用启动的时候直接产生一个单例对象。然后永久驻存在内存的方式来解决。
    • 单例模式可以再系统设置全局访问点。优化共享资源的访问。例如可以设计一个单例类,负责所有数据表的映射。

     

    2、单例实现方式

    先来看一个普通场景:

    这种普通的方法会在大的访问量下出现内存的消耗!

    每个请求到来,都需要在内存里创建一个实例,再通过该实例执行指定的方法。

    那么问题来了...如果并发量大的话,内存里就会存在非常多功能上一模一样的对象。

    #!/usr/bin/env python
    #coding:utf-8
    from wsgiref.simple_server import make_server
    
    
    class DbHelper(object):
    
        def __init__(self):
            self.hostname = '1.1.1.1'
            self.port = 3306
            self.password = 'pwd'
            self.username = 'root'
    
        def fetch(self):
        # 连接数据库
        # 拼接sql语句
        # 操作
            return 'fetch'
    
        def create(self):
        # 连接数据库
        # 拼接sql语句
        # 操作
            return 'create'
    
        def remove(self):
        # 连接数据库
        # 拼接sql语句
        # 操作
            return 'remove'
    
        def modify(self):
        # 连接数据库
        # 拼接sql语句
        # 操作
            return 'modify'
    
    
    class Handler(object):
    
        def index(self):
            # 创建对象
            db = DbHelper()
            print id(db)
            db.fetch()
    
            return 'index'
    
        def news(self):
            return 'news'
    
    
    def RunServer(environ, start_response):
        start_response('200 OK', [('Content-Type', 'text/html')])
        url = environ['PATH_INFO']
        temp = url.split('/')[1]
        obj = Handler()
        is_exist = hasattr(obj, temp)
        if is_exist:
            func = getattr(obj, temp)
            ret = func()
            return ret
        else:
            return '404 not found'
    
    if __name__ == '__main__':
        httpd = make_server('', 8001, RunServer)
        print "Serving HTTP on port 8001..."
        httpd.serve_forever()
    

     

     

    上面的例子就是对数据库的操作。当操作量非常多时,会产生大量的内存消耗,因为每一个请求都创建了一份实例

    对于这些功能相同的对象可以在内存中仅创建一个,需要时都去调用,也是极好的!!!

    单例模式用来保证内存中仅存在一个实例!!!通过 类方法@classmethod 静态方法 @staticmethod都可以实现
     

    原理:通过面向对象的特性,构造出单例模式:

    • 类方法     @classmethod   (cls=当前类)  触发者是类,用类直接调用,括号里只能有一个参数cls
                             对静态方法的约束,只能有一个参数,参数在传值的时候自动把当前类传入。单例模式时用到。
    • 静态方法  属于类   @staticmethod   触发者类,括号里不需要参数()可以有多个参数
                      类加上静态方法=一个函数 。创建对象就可以访问方法,就像创建了函数。如果程序全部要求用面向对象做,而不用函数,静态方法才有用。

     

    为什么要有类方法和静态方法?

             因为如果没有这两种方法,在调用时就会先创建对象在去调用方法。而这两种方法都可以直接通过类来调用,节省的内存。
     
    #!/usr/bin/env python
    #coding:utf-8
    from wsgiref.simple_server import make_server
    
    # ########### 单例类定义 ###########
    
    class DbHelper(object):
    
      __instance = None        #创建一个私有静态字段,用来保存内存中永远存在的的实例字段
    
    
        def __init__(self):
            self.hostname = '1.1.1.1'
            self.port = 3306
            self.password = 'pwd'
            self.username = 'root'
    
        @staticmethod
        def singleton():
            if DbHelper.__instance:
                return DbHelper.__instance
            else:
                DbHelper.__instance = DbHelper()
                return DbHelper.__instance
    
        def fetch(self):
        # 连接数据库
        # 拼接sql语句
        # 操作
            pass
    
        def create(self):
        # 连接数据库
        # 拼接sql语句
        # 操作
            pass
    
        def remove(self):
        # 连接数据库
        # 拼接sql语句
        # 操作
            pass
    
        def modify(self):
        # 连接数据库
        # 拼接sql语句
        # 操作
            pass
    
    
    class Handler(object):
    
        def index(self):
            obj =  DbHelper.singleton()   #通过类直接调用静态方法
            print id(obj)
            obj.create()
            return 'index'
    
        def news(self):
            return 'news'
    
    
    def RunServer(environ, start_response):
        start_response('200 OK', [('Content-Type', 'text/html')])
        url = environ['PATH_INFO']
        temp = url.split('/')[1]
        obj = Handler()
        is_exist = hasattr(obj, temp)
        if is_exist:
            func = getattr(obj, temp)
            ret = func()
            return ret
        else:
            return '404 not found'
    
    if __name__ == '__main__':
        httpd = make_server('', 8001, RunServer)
        print "Serving HTTP on port 8001..."
        httpd.serve_forever()

      

     

  • 相关阅读:
    springboot配置redis缓存
    【spark】local模式运行
    mybatis从入门到精通(二) 增删查改
    学习设计模式
    学习设计模式
    mybatis从入门到精通(一) 入门
    学习NIO 之 使用方法
    学习 NIO 之 零拷贝
    Java并发
    学习设计模式
  • 原文地址:https://www.cnblogs.com/chenchao1990/p/5376956.html
Copyright © 2020-2023  润新知