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》参考文献との違い

  • 引数の型で処理を選択する代わりに、メソッド名に実行時の型情報を埋め込みます。

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"
    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)

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》参考文献との違い

  • 引数の型で処理を選択する代わりに、メソッド名に実行時の型情報を埋め込みます。