Python 设计模式—访问者模式
今日分享主题:Python 设计模式之访问者模式。
定义
访问者模式是指封装一些作用于某种数据结构中的各元素的操作,它可以在不改变数据结构的前提下定义于作用于这些元素的新操作。
应用场景
1、要遍历不同的对象,根据对象进行不同的操作的场景;
2、当一个对象被多个不同对象顺次处理的情况,可以考虑使用访问者模式;
3、报表生成器也可以使用访问者模式实现,报表的数据源由多个不同的对象提供,每个对象都是Visitor,报表这个Element顺次Accept各访问者完善并生成对象。
Python 代码实现
1class Person(object): 2 pass 3 4class Man(Person): 5 pass 6 7class Woman(Person): 8 pass 9 10class Girl(Woman,Man): 11 pass 12 13class Son(Man, Woman): 14 pass 15 16class Visitor(object): 17 def visit(self, person, *args, **kwargs): 18 meth = None 19 #为了方便且快速地看清继承关系和顺序,可以用__mro__方法来获取这个类的调用顺序。 20 for cls in person.__class__.__mro__: 21 # print(cls) 22 meth_name = 'visit_'+cls.__name__ 23 # print("----",meth_name) 24 # print(self) 25 ''' 26 这里讲解一下:Python的hasattr(),getattr(),setattr()函数使用方法 27 一:hasattr(object, name) 28 判断一个对象里面是否有name属性或者name方法,返回BOOL值,有name特性返回True, 否则返回False。 29 二:getattr(object, name[,default]) 30 获取对象object的属性或者方法,如果存在打印出来,如果不存在,打印出默认值,默认值可选。 31 三:setattr(object, name, values) 32 给对象的属性赋值,若属性不存在,先创建再赋值。 33 ''' 34 meth = getattr(self, meth_name, None) 35 if meth: 36 break 37 38 if not meth: 39 meth = self.generic_visit 40 return meth(person, *args, **kwargs) 41 42 #普通访问入口 43 def generic_visit(self, person, *args, **kwargs): 44 # 这里可以写处理逻辑 45 print('generic_visit '+person.__class__.__name__) 46 47 #妇女访问入口 48 def visit_Woman(self, person, *args, **kwargs): 49 # 这里可以写处理逻辑 50 print('visit_Woman '+person.__class__.__name__) 51 52 #男人访问入口 53 def visit_Man(self, person, *args, **kwargs): 54 # 这里可以写处理逻辑 55 print('visit_Man '+person.__class__.__name__) 56 57if __name__ == '__main__': 58 p=Person() 59 man = Man() 60 woman = Woman() 61 girl = Girl() 62 son = Son() 63 64 visitor = Visitor() 65 visitor.visit(p) 66 visitor.visit(man) 67 visitor.visit(son) 68 visitor.visit(woman) 69 visitor.visit(girl)
输出结果如下:
1generic_visit Person
2visit_Man Man
3visit_Man Son
4visit_Woman Woman
5visit_Woman Girl
备注
class Man(Person)--->这里会在类的继承关系中会指定调用visit_Man方法
class Son(Man,Woman)--->这里会在类的继承关系中优先找到并调用visit_Man方法
class Woman(Person)--->这里会在类的继承关系中会指定调用visit_Woman方法
class Girl(Woman,Man)--->这里会在类的继承关系中优先找到并调用visit_Woman方法
找到了对应的方法就可以执行对应的业务逻辑。
优点:
1、将不同的职责非常明确地分离开来,符合单一职责原则;
2、职责的分开也直接导致扩展非常优良,灵活性非常高,加减元素和访问者都非常容易。
欢迎关注【无量测试之道】公众号,回复【领取资源】
Python编程学习资源干货、
Python+Appium框架APP的UI自动化、
Python+Selenium框架Web的UI自动化、
Python+Unittest框架API自动化、
资源和代码 免费送啦~
文章下方有公众号二维码,可直接微信扫一扫关注即可。
备注:我的个人公众号已正式开通,致力于测试技术的分享,包含:大数据测试、功能测试,测试开发,API接口自动化、测试运维、UI自动化测试等,微信搜索公众号:“无量测试之道”,或扫描下方二维码:
添加关注,让我们一起共同成长!