MATLAB 2018-05-21
python中的模块是最天然的单例模式
单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例。
单例模式是一种常见的设计模式,在计算机系统中,线程池、缓存、日志对象、对话框、打印机、数据库操作、显卡的驱动程序常被设计成单例。
单例模式分3种:懒汉式单例、饿汉式单例、登记式单例。
单例模式有以下3个特点:
只能有一个实例。
必须自行创建这个实例。
必须给其他对象提供这一实例。
python中的单例
class SingleTon(object):
def __new__(cls, *args, **kwargs):
if not hasattr(cls, '_instance'):
cls._instance = super(SingleTon, cls).__new__(cls, *args, **kwargs)
return cls._instance
class MyCls(SingleTon):
a =
a = MyCls()
b = MyCls()
print(id(a), id(b))创建实例时把所有实例的__dict__指向同一字典,这样他们具有相同的属性和方法
class SingleTon(object):
_state = {}
def __new__(cls, *args, **kwargs):
obj = super(SingleTon, cls).__new__(cls, *args, **kwargs)
obj.__dict__ = cls._state
return obj
class MyCls(SingleTon):
a=def singleTon(cls,*args,**kwargs):
instance={}
def inner():
if cls not in instance:
instance[cls]=cls(*args,**kwargs)
return instance[cls]
return inner
@singleTon
class Mycls(object):
pass
a=Mycls()
b=Mycls()
print(a is b)工厂模式是我们最常用的实例化对象模式,是用工厂方法代替new操作的一种模式。
使用工厂模式的好处是,如果你想要更改所实例化的类名等,则只需更改该工厂方法内容即可,不需逐一寻找代码中具体实例化的地方(new处)修改了。为系统结构提供灵活的动态扩展机制,减少了耦合。
# 由于python没有抽象类,接口这个概念,要实现抽象类或者接口需要通过abc模块来实现
from abc import abstractclassmethod, ABCMeta
class Animal(object):
__metaclass__ = ABCMeta
@abstractclassmethod
def detail(self):
pass
class Human(Animal):
def detail(self):
print('这是人类')
class Dog(Animal):
def detail(self):
print('这是狗')
class SimpleFactory(object):
@staticmethod
def createHuman():
return Human()
@staticmethod
def createDog():
return Dog()
SimpleFactory.createDog().detail()
SimpleFactory.createHuman().detail()注册模式,解决全局共享和交换对象。已经创建好的对象,挂在到某个全局可以使用的数组上,在需要使用的时候,直接从该数组上获取即可。将对象注册到全局的树上。任何地方直接去访问。
# 注册模式
regObj = {}
class Register(object):
def set(self, cls):
regObj[cls] = cls
def get(self, cls):
return regObj[cls]
def unset(self, cls):
regObj.pop(cls)策略模式是对象的行为模式,用意是对一组算法的封装。动态的选择需要的算法并使用。
策略模式指的是程序中涉及决策控制的一种模式。策略模式功能非常强大,因为这个设计模式本身的核心思想就是面向对象编程的多形性思想。
策略模式的三个角色:
抽象策略角色
具体策略角色
环境角色(对抽象策略角色的引用)
定义抽象角色类(定义好各个实现的共同抽象方法)
定义具体策略类(具体实现父类的共同方法)
定义环境角色类(私有化申明抽象角色变量,重载构造方法,执行抽象方法)
就在编程领域之外,有许多例子是关于策略模式的。例如:
如果我需要在早晨从家里出发去上班,我可以有几个策略考虑:我可以乘坐地铁,乘坐公交车,走路或其它的途径。每个策略可以得到相同的结果,但是使用了不同的资源。
策略模式的代码实例:
# 策略模式
# 由于python没有抽象类,接口这个概念,要实现抽象类或者接口需要通过abc模块来实现
from abc import abstractclassmethod, ABCMeta
# 我们定义一个聚会的抽象类,然后再唱歌、吃饭策略
class Gather(object):
__metaclass__=ABCMeta
@abstractclassmethod
def haveFun(self):
pass
class Sing(Gather):
def haveFun(self):
print('唱歌')
class Eat(Gather):
def haveFun(self):
print('吃饭')
class Strategy(object):
@staticmethod
def selectWay(flag):
if flag:
return Sing()
else:
return Eat()
Strategy.selectWay(True).haveFun()观察者模式(Observer),当一个对象状态发生变化时,依赖它的对象全部会收到通知,并自动更新。
场景:一个事件发生后,要执行一连串更新操作。传统的编程方式,就是在事件的代码之后直接加入处理的逻辑。当更新的逻辑增多之后,代码会变得难以维护。这种方式是耦合的,侵入式的,增加新的逻辑需要修改事件的主体代码。
观察者模式实现了低耦合,非侵入式的通知与更新机制。 定义一个事件触发抽象类。
# 观察者模式
class Observer(object):
def __init__(self):
self._observers = []
# 添加观察者
def attach(self, obs):
if obs not in self._observers:
self._observers.append(obs)
# 取消添加观察者
def detach(self, obs):
if obs in self._observers:
self._observers.remove(obs)
# 通知观察者数据变化
def notify(self, modifier=None):
for obs in self._observers:
if modifier != obs:
obs.update(self)
class Data(Observer):
def __init__(self, name=''):
super(Data, self).__init__()
self.name = name
self._data = 0
@property
def data(self):
return self._data
@data.setter
def data(self, value):
self._data = value
self.notify()
# 这里有2个被观察者,也就是依赖的对象,每次Data有改变,这2个view都会变动
class HexViewer(object):
def update(self, subject):
print('HexViewer: Subject %s has data 0x%x' % (subject.name, subject.data))
class DecimalViewer(object):
def update(self, subject):
print('DecimalViewer: Subject %s has data %d' % (subject.name, subject.data))
if __name__ == '__main__':
data1 = Data('Data 1')
data2 = Data('Data 2')
view1 = DecimalViewer()
view2 = HexViewer()
data1.attach(view1)
data1.attach(view2)
data2.attach(view2)
data2.attach(view1)
print ("Setting Data 1 = 10")
data1.data = 10
print ("Setting Data 2 = 15")
data2.data = 15
print ("Setting Data 1 = 3")
data1.data = 3
print ("Setting Data 2 = 5")
data2.data = 5
print ("Update data1's view2 Because view1 is be filtered")
data1.notify(modifier=view1)
print ("Detach HexViewer from data1 and data2.")
data1.detach(view2)
data2.detach(view2)
print ("Setting Data 1 = 10")
data1.data = 10
print ("Setting Data 2 = 15")
data2.data = 15 class Singleton: def __new__: # 关键在于这,每一次实例化的时候,我们都只会返回这同一个instance对象 if not hasattr: cls.instance =