设计模式是什么?
设计模式是经过总结、优化的,对我们经常会碰到的一些编程问题的可重用解决方案。一个设计模式并不像一个类或一个库那样能够直接作用于我们的代码。反之,设计模式更为高级,它是一种必须在特定情形下实现的一种方法模板。设计模式不会绑定具体的编程语言。一个好的设计模式应该能够用大部分编程语言实现(如果做不到全部的话,具体取决于语言特性)。最为重要的是,设计模式也是一把双刃剑,如果设计模式被用在不恰当的情形下将会造成灾难,进而带来无穷的麻烦。然而如果设计模式在正确的时间被用在正确地地方,它将是你的救星。
这里列举了三种最基本的设计模式:
1、结构化模式,通常用来处理实体之间的关系,使得这些实体能够更好地协同工作。
外观模式(Facade); 适配器模式(Adapter); 代理模式(Proxy); 装饰模式(Decorator); 桥模式(Bridge); 组合模式(Composite); 享元模式(Flyweight)。
2、创建模式,提供实例化的方法,为适合的状况提供相应的对象创建方法。
简单工厂模式(Simple Factory); 工厂方法模式(Factory Method); 抽象工厂模式(Abstract Factory); 创建者模式(Builder); 原型模式(Prototype); 单例模式(Singleton)。
3、行为模式,用于在不同的实体建进行通信,为实体之间的通信提供更容易,更灵活的通信方法。
模板方法模式(Template Method); 观察者模式(Observer); 状态模式(State); 策略模式(Strategy); 职责链模式(Chain of Responsibility); 命令模式(Command); 访问者模式(Visitor); 调停者模式(Mediator); 备忘录模式(Memento); 迭代器模式(Iterator); 解释器模式(Interpreter)。
我们为什么要使用设计模式?
从理论上来说,设计模式是对程序问题比较好的解决方案。无数的程序员都曾经遇到过这些问题,并且他们使用这些解决方案去处理这些问题。所以当你遇到同样的问题,为什么要去想着创建一个解决方案而不是用现成的并且被证明是有效的呢?
单例模式:
单例,顾名思义单个实例,单利模式存在的目的是保证当前内存中仅存在单个实例,避免内存浪费
对于Python单例模式,创建对象时不能再直接使用:obj = Foo(),而应该调用特殊的方法:obj = Foo.singleton() 。
方法一、
class Instance: __instance=None # 私有类属性 def __init__(self): self.name=‘linux‘ self.passwd=‘kkkkk‘ @staticmethod def get_instance(): if not Instance.__instance: # 如果私有类属性为空的话,创建一个实例 Instance.__instance = Instance() return Instance.__instance # 不为空的话,直接返回一个实例 obj1=Instance.get_instance() # 执行静态方法,创建一个实例赋值给obj1 obj2=Instance.get_instance() # 执行静态方法,将私有类属性保存的对象赋值给obj2 print(obj1) # <__main__.Instance object at 0x0000021AEDF56048> print(obj2) # <__main__.Instance object at 0x0000021AEDF56048>
方法二、
class Foo: instance = None def __init__(self,name): self.name = name @classmethod def get_instance(cls): if cls.instance: return cls.instance else: obj = cls("python") cls.instance = obj return obj obj = Foo.get_instance() print(obj) obj1 = Foo.get_instance() print(obj1)
方法三、
class Singleton(): def __new__(cls, *args, **kwargs): if not hasattr(cls,‘_instance‘): cls._instance=super(Singleton,cls).__new__(cls,*args, **kwargs) return cls._instance class A(Singleton): pass a=A() b=A() print(a is b)
方法四、
class Singleton(type): def __call__(cls, *args, **kwargs): if not hasattr(cls, ‘_instance‘): cls._instance = super(Singleton, cls).__call__(*args, **kwargs) return cls._instance class A(metaclass=Singleton): # __metaclass__ = Singleton pass a = A() b = A() print(a is b)
方法五、
class SingMetaclass(type): def __call__(self, *args, **kwargs): if not hasattr(self, ‘instance‘): # self.instance = super(SingMetaclass, cls).__new__(cls, name, base, attrs) # self.instance = self.__new__(self, *args, **kwargs) # 下面这种方式也行,但是没有注释掉的好理解 self.instance = super().__call__(*args, **kwargs) return self.instance class A(metaclass=SingMetaclass): pass
后续用到其他模式再进行添加!!
总结
在本文中,我只列举了几个我再编程中觉得十分重要的设计模式来讲,除此之外还有很多设计模式需要学习。如果你对其他的设计模式感兴趣,维基百科的设计模式部分可以提供很多信息。如果还嫌不够,你可以看看四人帮的《设计模式:可复用面向对象软件的基础》一书,此书是关于设计模式的经典之作。
最后一件事:当使用设计模式时,确保你是用来解决正确地问题。正如我之前提到的,设计模式是把双刃剑:如果使用不当,它们会造成潜在的问题;如果使用得当,它们则将是不可或缺的。