Aha!设计模式(107)-访问者模式(3)

网友投稿 483 2022-11-12

Aha!设计模式(107)-访问者模式(3)

Aha!设计模式(107)-访问者模式(3)

示例代码

我们使用一个接近生活的例子来说明访问者模式。假设有一个小区,居民家里一般都会安装电表、水表,部分家里会安装煤气表。

# 电表class ElecMeter: # 抄表 def read(self): returnrandom.randint(100, 300) # 检查 def check(self): returnrandom.randint(0, 1) # 更换 def replace(self): print('ElecMeter replaced.') # 接受访问者 def accept(self, visitor): visitor.visit_e_meter(self)# 水表class WaterMeter: # 抄表 def read(self): returnrandom.randint(10, 50) # 检查 def check(self): returnrandom.randint(0, 1) # 更换 def replace(self): print('WaterMeter replaced.') # 接受访问者 def accept(self, visitor): visitor.visit_w_meter(self)# 煤气表class GassMeter: # 抄表 def read(self): returnrandom.randint(5, 10) # 检查 def check(self): returnrandom.randint(0, 1) # 修理 def repair(self): print('GassMeter repaired.') # 接受访问者 def accept(self, visitor): visitor.visit_g_meter(self)

上述各类分别是电表类ElemMeter,水表类WaterMeter和煤气表类GassMeter。因为是示例代码,它们的构造大部分相同,都支持抄表,检查和接受访问者功能;不同的是水表和电表支持更换,而煤气表只支持修理。由于是示例代码,所有计量表的返回值都由随机数产生。

class Home: def __init__(self,e_meter, w_meter, g_meter): self.e_meter= e_meter self.w_meter= w_meter self.g_meter= g_meter def accept(self, visitor): if self.e_meter: self.e_meter.accept(visitor) if self.w_meter: self.w_meter.accept(visitor) if self.g_meter: self.g_meter.accept(visitor)

房屋类Home作为载体,管理电表,水表和煤气表的信息。当访问者入户访问时,负责将调用各计量表的accept接口以接纳访问者visitor。每个类中实际调用的函数由中各类的accept方法决定。

class MeterReader: def __init__(self): self.e_value= 0 self.w_value= 0 self.g_value= 0 # 抄电表 def visit_e_meter(self, e_meter): self.e_value= self.e_value + e_meter.read() # 抄水表 def visit_w_meter(self, w_meter): self.w_value= self.w_value + w_meter.read() # 抄煤气表 def visit_g_meter(self, g_meter): self.g_value= self.g_value + g_meter.read() # 输出结果 def __str__(self): ret = 'e_value:'+ str(self.e_value)+ '\n' ret = ret + 'w_value:' + str(self.w_value)+ '\n' ret = ret + 'g_value:' + str(self.g_value) + '\n' return ret

抄表员类MeterReader的职责就是读取所有计量表的读数值并汇总。

# 修理师傅class MeterRepairMan: def __init__(self): self.repair_counter= 0 # 检查,更换电表 def visit_e_meter(self, e_meter): ifnot e_meter.check(): e_meter.replace() self.repair_counter= self.repair_counter + 1 # 检查,更换水表 def visit_w_meter(self, w_meter): ifnot w_meter.check(): w_meter.replace() self.repair_counter= self.repair_counter + 1 # 检查,修理煤气表 def visit_g_meter(self, g_meter): ifnot g_meter.check(): g_meter.repair() self.repair_counter= self.repair_counter + 1 # 输出结果 def __str__(self): return 'repaircounter:' + str(self.repair_counter)

修理师傅会分别检查电表、水表、煤气表的状态,如果出现问题,就进行更换或修理。

if __name__ == '__main__': # 构建住宅区 homes =[] homes.append(Home(ElecMeter(),WaterMeter(), GassMeter())) homes.append(Home(ElecMeter(), WaterMeter(),None)) # 抄表 mr =MeterReader() for hin homes: h.accept(mr) print(mr) # 检修 mrm =MeterRepairMan() for hin homes: h.accept(mrm) print(mrm)

上述代码首先构建了一个两户居民的小区,然后分别接受了抄表员和检修师傅的访问,其执行结果如代码 4‑62所示。由于代码中使用了随机数,因此每次结果都会不同。

e_value:395w_value:52g_value:6ElecMeter replaced.WaterMeter replaced.GassMeter replaced.ElecMeter replaced.repair counter:4

只要决定了访问者类和要素类之间的关系,就可以根据需求增加具象访问者类的类型,对于任意数据结构进行访问。

觉得本文有帮助?请分享给更多人。

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:log4j升级log4j2遇到的问题及解决方式
下一篇:Tkinter编程应知应会(6)-构建按钮控件
相关文章

 发表评论

暂时没有评论,来抢沙发吧~