设计模式在Java里面这个是必须的中高阶内容。而很少看到Python里面刻意去讲这个,关于Python实现的设计模式,一直以来是自己比较好奇而且想深入学习的一个点。
需要吐槽的是自己买了本纸质书,按照书名是可以精通Python设计模式了,里面有流程图,有代码,部分还有例子和执行结果。但是自己看起来总是感觉有些吃力,不是完全技术层面的困难,而是理解上的困难。
而换个思路,看看国内的一些朋友写的一些设计模式的总结,一看就懂。我都纳闷是不是文化上的差异导致的。
这个比较清晰。可以关注下。
https://github.com/w392807287/Design_pattern_of_python
这个的star都超过14000个了。
https://github.com/faif/python-patterns/blob/master/creational/borg.py
我们先来简单看下工厂模式
如下是工厂方法的实现,里面用到了字典来做键值的映射。
#!/usr/bin/python
# coding:utf8
'''
Factory Method
'''
class ChinaGetter:
"""A simple localizer a la gettext"""
def __init__(self):
self.trans = dict(jianrong=u"杨建荣", jianrong_notes=u"学习笔记")
def get(self, msgid):
"""We'll punt if we don't have a translation"""
try:
return self.trans[msgid]
except KeyError:
return str(msgid)
class EnglishGetter:
"""Simply echoes the msg ids"""
def __init__(self):
self.trans = dict(jeanron100=u"jeanron100...", mysql=u"MySQL", oracle=u"Oracle")
def get(self, msgid):
try:
return self.trans[msgid]
except KeyError:
return str(msgid)
def get_localizer(language="English"):
"""The factory method"""
languages = dict(English=EnglishGetter, China=ChinaGetter)
return languages[language]()
# Create our localizers
e, g = get_localizer("English"), get_localizer("China")
# Localize some text
for msgid in "jeanron100 jianrong mysql oracle".split():
print(e.get(msgid), g.get(msgid))
执行结果如下:
(u'jeanron100...', 'jeanron100')
('jianrong', u'\u6768\u5efa\u8363')
(u'MySQL', 'mysql')
(u'Oracle', 'oracle')
而使用抽象工厂,使用了random来做一个动态匹配。这个例子参考了开篇的第一个链接的例子,里面的getFactory方法会随机得到一个工厂的实例化对象,而对于应用来说这个匹配的过程是透明的。
#!/usr/bin/python
# coding:utf8
'''
Abstract Factory
'''
import random
class PetShop:
"""A pet shop"""
def __init__(self, animal_factory=None):
"""pet_factory is our abstract factory.
We can set it at will."""
self.pet_factory = animal_factory
def show_pet(self):
"""Creates and shows a pet using the
abstract factory"""
pet = self.pet_factory.get_pet()
print("This is a lovely", str(pet))
print("It says", pet.speak())
print("It eats", self.pet_factory.get_food())
# Stuff that our factory makes
class Dog:
def speak(self):
return "woof"
def __str__(self):
return "Dog"
class Cat:
def speak(self):
return "meow"
def __str__(self):
return "Cat"
# Factory classes
class DogFactory:
def get_pet(self):
return Dog()
def get_food(self):
return "dog food"
class CatFactory:
def get_pet(self):
return Cat()
def get_food(self):
return "cat food"
# Create the proper family
def get_factory():
"""Let's be dynamic!"""
return random.choice([DogFactory, CatFactory])()
# Show pets with various factories
if __name__ == "__main__":
shop = PetShop()
for i in range(3):
shop.pet_factory = get_factory()
shop.show_pet()
print("=" * 20)
#print random.choice([1,2,3,4,5])
执行结果如下:
('This is a lovely', 'Cat')
('It says', 'meow')
('It eats', 'cat food')
====================
('This is a lovely', 'Cat')
('It says', 'meow')
('It eats', 'cat food')
====================
('This is a lovely', 'Dog')
('It says', 'woof')
('It eats', 'dog food')
====================
有了这些铺垫,对于Python设计模式的实现就有了一个初步的认识和理解,后续做一些改进就可以循序渐进了。