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