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_WPF(Window):    # Form            # Visitor::ObjectStructure
  • Form に代えて、Window を拡張しています。
    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):
        e = ListBox(
            Width=216, Height=156,  # Size = Size(216, 186)
            )
        Canvas.SetLeft(e, 32)       # Location = Point(32, 32)
        Canvas.SetTop (e, 32)
        return e
  • System.Windows.Forms.ListBox に代えて、System.Windows.Controls.ListBox を利用しています。
  • Size に代えて、Width/Height に値を設定しています。
  • Location に代えて、SetLeft/SetTop を利用しています。
    def _btCompute(self):
        e = Button(
            Width=72, Height=24,    # Size = Size(72, 24)
            Content="Compute",      # Text
            )
        Canvas.SetLeft(e, 88)       # Location = Point(88, 232)
        Canvas.SetTop (e, 202)
        e.Click += self.btCompute_Click
        return e
  • System.Windows.Forms.Button に代えて、System.Windows.Controls.Button を利用しています。
  • Size に代えて、Width/Height に値を設定しています。
  • Location に代えて、SetLeft/SetTop を利用しています。
    def _Controls(self):
        self.Content = Canvas()
        self.Width = 292            # ClientSize = Size(292, 273)
        self.Height = 273
        for e in self.lsVac, self.btCompute:
            self.Content.Children.Add(e)    # .Controls
        self.Text = "Visitor demo"
  • Canvas 内に、各コントロールを配置します。
  • ClientSize に代えて、Width/Height に値を設定しています。
  • Controls に代えて、Children に子要素を追加しています。
    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_WPF.py


  • WPF アプリケーションとして、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/03/21, ver.2.0, WPF
#    2008/09/28, ver.2.1, IronPython 1.1.2 
#===============================================================================
import clr
#
clr.AddReference("PresentationFramework")
clr.AddReference("WindowsBase")
from System.Windows import *
from System.Windows.Controls 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》参考文献との違い

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

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

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