10. 设计模式:
1. _new_()的作用:
-
真正构造一个instance并return,如果不return,那么就没有instance
-
系统默认隐式地调用这两个魔术方法,当然,自己也可以重写,以及显式调用
class Animal(object):
def init():
print("我是Animal的init,没有得到instance ")
def new(cls): #因为没有return 一个instance,所以上面的init就不会被调用
print("我是Animal的new,没有创造instance,也没有return出去instance ")
a = Animal()
print(' ')class Temp(object):
def init(self):
print("我是Temp的init ")
def new(cls):
print("我是Temp的new ")
return super().new(cls) #调用父类的new,构造一个对象class People(object):
def init(self): #当前这个self默认接收了new方法return的instance,并对这个instance做init
print("我是People的init ")
def new(cls):
print("我是People的new,我创造了一个instance并return出去了 ")
instance = super().new(cls) #调用父类的new,构造一个对象, 隶属于People
#instance = Temp() #调用其他类产生一个instance,隶属于Temp,但没法调用people的init;return instance #把这个instance返回出去
p = People()
print(p,' ')
2. 单例模式
某个class创建实例的开销极大,而且一个对象足够使用,就用单例模式
-
实现一:通过调用类方法返回一个instance,每次想得到一个新的instance都这样操作
class User(object):
__instance=Nonedef __init__(self,name): self.name=name @classmethod #类方法 def get_instance(cls,name): #由上面的init说明这里要构造一个形参为name if not cls.__instance: #如果__instance 为None cls.__instance = User(name) #之后就去__init__()把当前这个instance的name设置好 return cls.__instance #确保只构造了一个instance,并且这个instance的name已经设置好
u1 = User.get_instance("zs") #调用类方法来获得instance,而不是一般的new一个instance
u2 = User.get_instance("ls")u3=User("ww")
print(u1==u2)
==判断表达式如果返回True,这两个对象是一个对象,并且内存地址相同
print(u1.name, u2.name) #分析代码过程,打印的是'zs'
print("u1对象的内存地址:%s,u2对象的内存地址:%s"%(id(u1),id(u2)))
-
实现二:确保_new_()只返回一个instance,所以只制造了一个instance
class User(object):
__instance=None #私有的类属性 def __init__(self,name): self.name=name def __new__(cls,name): if not cls.__instance: #保证 __new__()返回的instance为恒定值,故而只有一个对象 cls.__instance = super().__new__(cls) return cls.__instance
u1 = User("zs")
u2 = User("ls")
print(u1.name,u2.name)
print(u1==u2)==判断表达式如果返回True,这两个对象是一个对象,并且内存地址相同
print("u1对象的内存地址:%s,u2对象的内存地址:%s"%(id(u1),id(u2)))
跟踪创建并初始化对象的过程:new(), init(), str(),
u1 = User("zs")它先执行
new的结果记为 I, 即 u1 == I
init的结果就是 I.name = 'zs',或者说 u1.name = 'zs'
此时还没有print(u1.name),所以不会激发str
继续执行u2 = User("ls")
new的结果也是: u2 == I, 那么此时 u2 == u1,进而u2.name == u1.name == 'zs'
init的结果是 I.name = 'ls', 所以进而 u2.name = u1.name == I.name = 'ls'
此时还没有print,所以str依旧没有激发,但是此刻 u1.name == u2.name == I.name = 'ls'
继续执行 print(u1.name,u2.name),激发了str, 故而打印 u1.name == u2.name == I.name = 'ls'
3. 工厂模式
- 帮助我们创建类的实例的一种方式,比直接new一个对象复杂
- 但使系统的可维护性(后期代码的修改量尽可能小)和可扩展性更强
- 当两个类的依赖关系已经存在的情况下,我们绝不可能干掉依赖关系。
借助工厂模式,能让这种依赖关系的可维护性和可扩展性更强:找一个第三方(两个class中间插入接口,借助接口对话)
以一个“人使用斧头为例”,引入工厂之后:
人不需要自己new斧头,而是调用工厂,从工厂得到斧头
而工厂内部就实现了创造不同类型斧头的工作
这样人和斧头就有了工厂这个接口,以后人的class里面就不会具体涉及斧头class
-
原始的做法:
class Person(object):
def init(self,name):
self.name=namedef work(self, axe_type): #人要传入斧头类型 print(self.name+"开始工作了") #person完成work,需要使用一把斧头 #在原始社会,人需要一把石 #axe = StoneAxe("花岗岩斧头") #使用钢铁的斧 axe = SteelAxe("加爵斧头") axe.cut_tree()
class Axe(object):
def init(self,name):
self.name=namedef cut_tree(self): print("%s斧头开始砍树"%self.name)
class StoneAxe(Axe):
def cut_tree(self):
print("使用石头做的斧头砍树")class SteelAxe(Axe):
def cut_tree(self):
print("使用钢铁做的斧头砍树")p = Person("zs")
p.work("Steel")
p.work("Stone")
-
简单工厂(工厂模式的简化版,使用了类的静态方法创建各种实例)
class Person(object):
def init(self,name):
self.name=namedef work(self, axe_type): #人要传入斧头类型
print(self.name+"开始工作了")
#person完成work,需要使用一把斧头#已经有工厂,person去找工厂生成一把斧头 axe =Factory.create_axe(axe_type) axe.cut_tree()
class Axe(object):
def init(self,name):
self.name=namedef cut_tree(self): print("%s斧头开始砍树"%self.name)
class StoneAxe(Axe):
def cut_tree(self):
print("使用石头做的斧头砍树")class SteelAxe(Axe):
def cut_tree(self):
print("使用钢铁做的斧头砍树")工厂类
class Factory(object):
#生产斧头,根据用户指定的类型来生产
@staticmethod #支持在class外部,直接用类名调用
def create_axe(axe_type):
if (axe_type == 'Stone'):
return StoneAxe("花岗岩斧头")
elif (axe_type == 'Steel'):
return SteelAxe("钢铁斧头")p = Person("zs")
p.work("Steel")
p.work("Stone")
-
工厂模式(使用基本工厂的子类——各种具体工厂类,来分担SinpleFactory的静态方法创建各种实例的工作,更加抽象和更具有可维护性)
class Person(object):
def init(self,name):
self.name=namedef work(self): print(self.name+"开始工作了") #person完成work,需要使用一把斧头 #已经有工厂,person去找工厂生成一把斧头 factory = Steel_Axe_Factory() #即根据Person需求请求具体的工厂{具体工厂继承自基类工厂} #factory = Steel_Axe_Factory() axe =factory.create_axe() axe.cut_tree()
class Axe(object):
def init(self,name):
self.name=namedef cut_tree(self): print("%s斧头开始砍树"%self.name)
class StoneAxe(Axe):
def cut_tree(self):
print("使用石头做的斧头砍树")class SteelAxe(Axe):
def cut_tree(self):
print("使用钢铁做的斧头砍树")工厂类
class Factory(object):
#生产斧头,根据用户指定的类型来生产
def create_axe(self):
passclass Stone_Axe_Factory(Factory):
def create_axe(self):
return StoneAxe("花岗岩斧头")class Steel_Axe_Factory(Factory):
def create_axe(self):
return SteelAxe("钢铁斧头")p = Person("zs")
p.work() #如果需要改需求,去work()里面改换一个具体工厂即可,当然继续优化