python的设计模式
最近在使用python开发项目,涉及到项目框架设计和系统设计,在设计系统功能模块及其关系的时候,考虑到解耦合,方便二次开发,避免不到要使用一些设计模式。随着慢慢的学习,发现python和java在开发过程中有很多不一样,虽说设计模式的思想是一样的,但在实现设计模式上有很大区别。
python没有类似java中的interface接口,可以直接继承使用。在python中存在非正式接口(鸭子类型)可以通过编写抽象类,然后继承这个抽象类实现里面的抽象方法,可以实现java的interface的功能。
如果它像鸭子一样说话和走路,那么它就是一只鸭子
class Aeroplane(abc.ABC):
@abc.abstractmethod
def fly(self):
pass
class Boeing(Aeroplane):
def fly(self):
print("Flying!")
b = Boeing()
从代码块中可以看出,声明定义一个抽象类和抽象方法,在实现类中继承实现抽象方法,也可以达到interface接口作用。
其实从设计思想来看,设计模式就是找到一种很好方法去解决某一类问题,和具体实现的语言没有关系。只是在JAVA语言中,设计模式使用的最为规范和广范,这也和语言特性有关,在python中,并没有这么强的规范和广范,原因就是python是动态语言,封装更多,把设计模式封装到函数里面,用户使用起来就比较随意了。
基本是所有的设计模式都是遵守以下七大设计原则的:
1、单一职责原则:一个类负责一项职责.
2、里氏替换原则:继承与派生的规则.(子类可替换父类)
3、依赖倒转原则:高层模块不应该依赖低层模块,二者都应该依赖其抽象;抽象不应该依赖细节;细节应该依赖抽象。即针对接口编程,不要针对实现编程。
4、接口隔离原则:建立单一接口,不要建立庞大臃肿的接口,尽量细化接口,接口中的方法尽量少。
5、迪米特法则:高内聚 低耦合 – high cohesion low coupling
6、开闭原则:一个软件实体如类、模块和函数应该对扩展开放,对修改关闭。
7、组合/聚合复用原则:尽量使用组合和聚合少使用继承的关系来达到复用的原则。
我们拿一个抽象工厂的设计模式当作例子看看,这个案例主要为了构建一个带有颜色的形状物体:
我们先看类图
- 首先,最低下有六个实体类,分别为3个和形状相关、3个和颜色相关,这么多类,我们每次都要New的话,不方便,也不好管理,会增加程序的复杂度。
- 然后,我们将3个同类型的类放在一起,由一个类进行控制选择使用哪一个类。就是Shape()这一层,也就是
简单工厂模式。 - 根据依赖倒转原则,高层不应该直接以来低层模块,在简单工厂之上,我们进行一层抽象,达到封装效果,方便统一管理,上层和下层也解耦合了,互不影响。
代码实现:
#!/usr/bin/env python
# -*- coding: utf-8 _*__
#implementation of the atbstract factory pattern
class AbstractFactory(object):
def getShape(slef):
return Shape()
def getColor(slef):
return Color()
class Shape(AbstractFactory):
#create based on class name
@staticmethod
def shapeFactory(type):
#return eval(type + "0")
if type == "Circle":
return Circle()
if type == "Square":
return Square()
assert 0 , "Bad shape creation: " + type
class Circle(Shape):
def __init__(self):
self.name = "Circle"
def draw(self):
print(self.name+" draw")
def erase(self):
print(self.name+" erase")
class Square(Shape):
def __init__(self):
self.name = "Square"
def draw(self):
print(self.name+' draw')
def erase(self):
print(self.name+" erase")
class Color(AbstractFactory):
#create based on class name
@staticmethod
def colorFactory(type):
#return eval(type + "0")
if type == "Red":
return Red()
if type == "Green":
return Green()
assert 0 , "Bad color creation: " + type
class Red(Color):
def __init__(self):
self.name = "Red"
def padding(self):
print(self.name+" padding")
def reset(self):
print(self.name+" reset")
class Green(Color):
def __init__(self):
self.name = "Green"
def padding(self):
print(self.name+" padding")
def reset(self):
print(self.name+" reset")
if __name__ == '__main__':
abstractFactory = AbstractFactory()
types = Shape.__subclasses__()
for type in types:
circle = abstractFactory.getShape().shapeFactory(type.__name__)
circle.draw()
circle.erase()
types = Color.__subclasses__()
for type in types:
color = abstractFactory.getColor().colorFactory(type.__name__)
color.padding()
color.reset()