cmdb项目,单例模式,

走远了吗. 提交于 2019-12-04 11:40:30

1.cmdb资产采集之后为什么不直接放到数据库里面?(api接口的作用)

我想中个问题更想问的时api接口作用吧

首先,我程序里面的api接口的作用是做资产采集的入库和资产变更的记录
为什么都通过api来做那?
第一点:
    因为我想以后要做运维自动化,所以避免不了会有很多系统来用资产信息,回来我这里获取,虽然我可以给他数据库的账号和密码,但是非常不安全,我只需要给它写一个接口就可以了,然后将数据返回给其他系统
第二点:
    在我们进行资产采集的时候,如果不使用api的话,就得在所有服务器上面存上数据库的账号和密码,也会不安全。

 

2.单例模式

字面意思就是:只有一个实例,并且只能实力化一次。(保证一个类仅有一个实例,并提供一个访问它的全局访问点。)

这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。注意:  1.单例类智能有一个实例  2.单例类必须自己创建自己的唯一实例  3.单例类必须给其他所有对象提供这一实例主要解决:  一个全局频繁使用的类创建和销毁如何使用:  当想控制实例数目,节约系统资源的时候如何解决:  判断视同是否已经有了这个单例,如果有则返回,没有则创建(构造函数必须是私有的)应用场景:  1、一个班级只有一个班主任。  2、Windows 是多进程多线程的,在操作一个文件的时候,就不可避免地出现多个进程或线程同时操作一个文件的现象,所以所有文件的处理必须通过唯一的实例来进行。  3、一些设备管理器常常设计为单例模式,比如一个电脑有两台打印机,在输出的时候就要处理不能两台打印机打印同一个文件。优点:  1.在内存中只有一个类的唯一实例,减少了内存的开销,尤其是频繁的创建和销毁实例  2.避免对资源的多重占用(比如写文件操作)缺点:  1.没有接口,不能继承  2.与单一职责原则冲突  3.一个类应该关系内部逻辑,而不关系外面怎么样来实力化注意事项:  getInstance() 方法中需要使用同步锁 synchronized (Singleton.class) 防止多线程同时进入造成 instance 被多次实例化。

 

 

多例模式

class Foo(object):
    def __init__(self,name,age):
        self.name = name
        self.age = age

    def func(self):
        msg = "%s-%s" % (self.name, self.age)
        print(msg)
        print(self)  # 打印出两个不同实例的内存地址

obj1 = Foo("kobe",19) # foo的一个对象/实例
obj1.func()

obj1 = Foo("admin",19) # foo的一个对象/实例
obj1.func()

 

错误的单例模式

class Foo(object):
    instance = None
    def __init__(self,name,age):
        self.name = name
        self.age = age

    def __new__(cls, *args, **kwargs):
        if not cls.instance:
            cls.instance = object.__new__(cls)
        return cls.instance

    def func(self):
        msg = "%s-%s" % (self.name, self.age)
        print(self)  # 打印出两个实例的内存地址
        return msg


obj1 = Foo("kobe",19) # foo的一个对象/实例
res1 = obj1.func()
print(res1)

obj2 = Foo("admin",18) # foo的一个对象/实例
res2 = obj2.func()
print(res2)# 注意在使用单例模式的时候,一般不写上__init__,因为__init__会将之前的实例的数据会覆盖掉。

 

基于__new__正确的单例模式

# 基于多线程的单例模式 错误版
import time
class SingLeton(object):
    instance = None
    def __init__(self):
        self.name = None
    def __new__(cls, *args, **kwargs):
        if not cls.instance:
            time.sleep(1)
            cls.instance = object.__new__(cls)
        return cls.instance

def task():
    obj = SingLeton()
    print(obj)

for i in range(10):
    t = threading.Thread(target=task)
    t.start()

# 基于多线程的单例模式是不成立的
# 因为全部的线程都去执行__new__方法去了,在遇到time.sleepde,会夯住
# 所以会在夯住之后继续的进行实力化,但是10个线程已经全部的通过了if not cls.instance:这句判断
# 所以还会实力化新的实例。所以基于多线程的单例模式的实例化要加上锁

# 基于多线程的单例模式 正确版

import time
import threading

class SingLeton(object):
    instance = None
    lock = threading.RLock()
    def __new__(cls, *args, **kwargs):

        if cls.instance:  # 是为了当最后又一个要实例化的时候,不需要操作锁了,节省资源
            return cls.instance

        with  cls.lock:  # 自动加锁和解锁
            if not cls.instance:
                time.sleep(1)
                cls.instance = object.__new__(cls)
            return cls.instance

def task():
    obj = SingLeton()
    print(obj)

for i in range(10):
    t = threading.Thread(target=task)
    t.start()

 

 

基于文件导入实现单例模式(在源码中的应用)

# xx.py
class Singleton(object):

    def __init__(self):
        self._registry = []

    def register(self,model_class):
        self._registry.append(model_class)
site = Singleton()

# xx2.py
import xx
xx.site

 

 

 

单例模式的应用场景
  1.django配置文件,只要加载一次,以后使用都用同一份值。

class Singleton(object):
    instance = None

    def __init__(self):
        self.k0 = 0
        self.k1 = 1
        self.k2 = 2
        ...

    def __new__(cls, *arg, **kawrgs):
        if not cls.instance:
            cls.instance = object.__new__(cls)
        return cls.instance
    
obj1 = Singleton()
obj2 = Singleton()
obj3 = Singleton()

 

   2.django的admin,在注册models中用,希望所有的model类注册到同一个列表中。

 pass

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!