Boss.cs
class Boss(Employee): # Visitor::ConcreteElement def __init__(self, name, salary, vdays, sdays, bonusDays=None): Employee.__init__(self, name, salary, vdays, sdays) self.bonusDays = bonusDays
def accept(self, v):
source = "v.visit_%s(self)"%self.__class__.__name__
eval(source) ; print source
《Note》参考文献との違い
- 引数の型で処理を選択する代わりに、メソッド名に実行時の型情報を埋め込みます。
Visitor.cs
class Visitor: # abstract # Visitor::Visitor def visit_Employee(self, emp): raise NotImplementedError("%s.visit_Employee" %self.__class__.__name__) def visit_Boss(self, bos): raise NotImplementedError("%s.visit_Boss" %self.__class__.__name__)
- abstract に代えて、例外 NotImplementedError を生成しています。
VacationVisitor.cs
class VacationVisitor(Visitor): # Visitor::ConcreteVisitor def __init__(self): self.totalDays = 0 def visit_Employee(self, emp): # visit(Employee emp) self.totalDays += emp.vacDays def visit_Boss(self, bos): # visit(Boss bos) self.totalDays += bos.vacDays
《Note》参考文献との違い
- 引数の型で処理を選択する代わりに、メソッド名に実行時の型情報を埋め込みます。
bVacationVisitor.cs
class bVacationVisitor(Visitor): # Visitor::ConcreteVisitor def __init__(self): self.totalDays = 0 def visit_Employee(self, emp): # visit(Employee emp) self.totalDays += emp.vacDays def visit_Boss(self, bos): # visit(Boss bos) self.totalDays += bos.vacDays self.totalDays += bos.bonusDays
《Note》参考文献との違い
- 引数の型で処理を選択する代わりに、メソッド名に実行時の型情報を埋め込みます。
Form1.cs
class Visitor_Forms(Form): # Visitor::ObjectStructure def __init__(self, **args): self.InitializeComponent() self.init()
def init(self):
self.empls = # Employee
for e in [
Employee("Susan Bear", 55000, 12, 1),
Employee("Adam Gehr", 150000, 9, 0),
Employee("Fred Harris", 50000, 15, 2),
Employee("David Oakley", 57000, 12, 2),
Employee("Larry Thomas", 100000, 20, 6),
Boss("Leslie Susi", 175000, 16, 4, bonusDays=12),
Boss("Laurence Byerly", 35000, 17, 6, bonusDays=17),
]:
self.empls.append(e)
- 配列に代えて、list を利用しています。
def InitializeComponent(self): self.lsVac = self._lsVac() self.btCompute = self._btCompute() self._Controls() def _lsVac(self): return ListBox( Location = Point(32, 32), Size = Size(216, 186), ) def _btCompute(self): e = Button( Location = Point(88, 232), Size = Size(72, 24), Text = "Compute", ) e.Click += self.btCompute_Click return e
def _Controls(self):
self.ClientSize = Size(292, 273)
for e in self.lsVac, self.btCompute:
self.Controls.Add(e)
self.Text = "Visitor demo"
- Controls に各コントロール e を追加します。
def btCompute_Click(self, sender, e): vac = VacationVisitor() bvac = bVacationVisitor() for e in self.empls: e.accept(vac) e.accept(bvac) self.lsVac.Items.Add("Total vacation days=%s" %vac.totalDays) self.lsVac.Items.Add("Total boss vacation days=%s"%bvac.totalDays)
__main__
if __name__ == "__main__": print __file__,"ver.1.1" form = Visitor_Forms() form.Text = form.__class__.__name__ Application.Run(form)
《参考文献》
- C# Design Patterns 31. The Visitor Pattern.
Visitor_Forms.py
- Windows Forms アプリケーションとして、IronPython で実現した事例を紹介します。
# -*- coding: utf-8 -*- #=============================================================================== # Copyright (C) 2000-2008, 小泉ひよ子とタマゴ倶楽部 # # History: Design Pattern # 2008/01/25, IronPython 1.1.1 (download) # 2008/08/22, IronPython 1.1.2 (download) # 2008/01/15, ver.1.0, Windows Forms # 2008/09/28, ver.2.1, IronPython 1.1.2 #=============================================================================== import clr clr.AddReference("System.Drawing") from System.Drawing import * clr.AddReference("System.Windows.Forms") from System.Windows.Forms import *
Employee.cs
class Employee: # Visitor::ConcreteElement def __init__(self, name, salary, vDays, sDays): self.name = name self.salary = salary self.sickDays = sDays self.vacDays = vDays
def accept(self, v):
source = "v.visit_%s(self)"%self.__class__.__name__
eval(source) ; print source
《Note》参考文献との違い
- 引数の型で処理を選択する代わりに、メソッド名に実行時の型情報を埋め込みます。