面向对象的设计原则
1、开放/封闭原则
类或对象及其方法对于扩展来说,应该是开放的,但是对于修改来说应该是封闭的。
优点:
现有的类不会被修改,因此退化的可能性小
它还有助于保持以前代码的向后兼容性
2、控制反转原则
高层的模块不应该依赖于低层的模块,它们应该都依赖于抽象。细节应该依赖于抽象,而不是抽象依赖于细节
优点:
消弱了模块间的紧耦合,因此消除了系统中的复杂性/刚性
由于在依赖模块之间有一个明确的抽象层(由钩子或参数提供),因此便于通过更好的方式处理模块之间的依赖关系
3、接口隔离原则
客户端不应该依赖于它们不需要使用的接口
优点:
它强制开发人员编写“瘦身型”接口,并使方法与接口紧密相关
防止向接口中随意添加方法
4、单一职责原则
类的职责单一,引起类变化的原因单一
优点:
每当一个功能发生变化时,除了特定的类需要改变外,其他类无需变动
此外,如果一个类有多种功能,那么依赖它的类必定会由于多种原因而经历多次修改,这是应该避免的
5、替换原则
派生类必须能够完全取代基类
模式的分类
三大类:
创建型模式
结构型模式
行为型模式
单例设计模式
意图:
确保类有且只有一个对象被创建
为对象提供一个访问点,以使程序可以全局访问该对象
控制共享资源的并行访问
1、经典实现classSingleton(object):
def__new__(cls ):
if nothasattr(cls,'instance'):
cls.instance=super(Singleton,cls)\
.__new__(cls)
returncls.instance
测试代码 :s=Singleton()
s1=Singleton()
print("s",s)
print("s1",s1)
结果:D:\Programs\python35\python.exe E:/workgroup/dl/pattern/singleton.py
s <__main__.singleton object at>
s1 <__main__.singleton object at>
运行结果显示地址相同表示同一个对象
2、单例模式中的懒汉式实例化
在导入模块的时候,可能会无意中创建一个对象,但当时根本用不到它。确保在实际需要时才创建对象。懒汉式实例化是一种节约资源并仅在需要时才创建他们的方式。
s=Singleton()时,会调用__init__方法,但没有创建新的对象,只有在调用Singleton.getInstance()时才会实例化。classSingleton:
__instance=None
def__init__(self):
if notSingleton.__instance:
print("__init__ methon called...")
else:
print("Instance already created:",\
self.getInstance())
@classmethod
defgetInstance(cls):
if notcls.__instance:
cls.__instance=Singleton()
returncls.__instance
测试代码:s=Singleton()
print("Object created",Singleton.getInstance())
s1=Singleton()
print("s",s)
print("s1",s1)
测试结果:D:\Programs\python35\python.exe E:/workgroup/dl/pattern/singleton2.py
__init__ methon called...
__init__ methon called...
Object created <__main__.singleton object at>
Instance already created: <__main__.singleton object at>
s <__main__.singleton object at>
s1 <__main__.singleton object at>
其中s,s1并不是同一地址。
3、Monostate单例模式
Gof单例指一个类有且只有一个对象,根据Alex Martelli的说法,通常程序员需要让实例共享相同的状态,而不是同一性,称为Monostate(单态)模式classBorg:
__shared_state={"1":"2"}
def__init__(self):
self.x=1
self.__dict__=self.__shared_state
pass
测试代码:b=Borg()
b1=Borg()
b.x=4
print("b",b)
print('b1',b1)
print("b.__dict__",b.__dict__)
print("b1.__dict__",b1.__dict__)
显示结果:D:\Programs\python35\python.exe E:/workgroup/dl/pattern/monostate.py
b <__main__.borg object at>
b1 <__main__.borg object at>
b.__dict__ {'1': '2', 'x': 4}
b1.__dict__ {'1': '2', 'x': 4}
地址不一样,但是内容是一样的。
4、元类
通过元类创建单例模式
元类是一个类的类,意味着该类是它的元类的实例classMetaSingleton(type):
__instances={}
def__call__(self, *args, **kwargs):
ifself not inself.__instances:
self.__instances[self]=\
super(MetaSingleton,self).\
__call__(*args,**kwargs)
returnself.__instances[self]
元类是类的类,__call__方法
对于已经存在的类来说,当需要创建对象时,将调用python的特殊方法__call__
测试:classLogger(metaclass=MetaSingleton):
pass
l1=Logger()
l2=Logger()
print(l1)
print(l2)
结果显示:D:\Programs\python35\python.exe E:/workgroup/dl/pattern/metasingleton.py
地址一样
实际应用
在数据库中应用classDatabase(metaclass=MetaSingleton):
connection=None
defconnect(self):
ifself.connection is None:
self.connection=sqlite3.\
connect('db.sqlite3')
self.cursorobj=self.\
connection.cursor()
returnself.cursorobj
实例调用过程
总结:
单例模式的缺点
全局变量可能在某处已经被误改,但是开发人员仍然认为它们没有发生变化,而变量还在应用程序的其他位置被使用
可能对同一对象创建多个应用。由于单例只创建一个对象,因此这种情况下会对同一个对象创建多个引用
所有依赖于全局变量的类都会由于一个类的改变而紧密耦为全局数据,从而可能在无意中影响另一个类
请关注公众号,跟进其他模式