第3章 Command パターン 2/4, IronPython

前の記事記事一覧次の記事

IronPython で学ぶ WPF プログラミングの世界《IronPython2.6》

Command パターン

《著》森こねこ・後藤いるか・小粒ちゃん《監修》小泉ひよ子とタマゴ倶楽部
第1版♪1995/07/02 ● 第2版♪2003/01/29 ● 第3版♪2008/04/28

■ 概要

WPF の特徴を活かして、デザインパターン Command を導入します。

イベントに呼応するアクションを規定したいときには〈GoF〉Command パターンを導入します。すると、密接に関係する「イベント/アクション」対を、再利用可能な「部品」として扱えます。

《Note》IronPython1.x 用に作成したセミナー課題を、IronPython2.6 で再構成しました。

■ 関連記事


2a)機能の要求:Command

Command::Command では、対象となる要素に共通するプロトコルを規定します。

class Command:                 # Command::Command
    def execute(self, sender, e):
        raise NotImplementedError("%s.execute"
            %self.__class__.__name__)

ここで規定したメソッド execute を、子孫クラスで再定義しないと、実行時に例外 NotImplementedError を生成するとともに、そのクラス名を出力します。たとえば、実行時に次のようなメッセージ

NotImplementedError: PaintColor.execute

が出力されるので、子孫クラス PaintColor でメソッド execute を再定義していないのが分かります。

2b)機能の実現:ConcreteCommand

Command::ConcreteCommand では、Command::Command で規定されたプロトコルに従って、各機能を実現します。

■ クラス PaintColor
class PaintColor(Button, Command):         # Command::ConcreteCommand
    def __init__(self, Content, panel):         
        self.panel = panel
        self.Content = Content
        self.Click += self.execute
    def execute(self, sender, e):
        e = sender.Content
        self.panel.Background = getattr(Brushes, e)

メソッド execute では、パネル panel の背景色を設定します。選択した項目(ボタン).Content に設定された値をもとに、背景 Background となるブラシ Brushes の色を設定します。

■ クラス FileOpen
class FileOpen(Button, Command):         # Command::ConcreteCommand
    def __init__(self, panel):
        self.panel = panel
        self.Content = "Open..."
        self.Click += self.execute
    def execute(self, sender, e):
        dialog = OpenFileDialog()
        dialog.ShowDialog()
        e = dialog.FileName.split("\\")[-1]
        brush = ImageBrush(
            ImageSource=BitmapImage(Uri("Flags/%s"%e, UriKind.Relative))
            )
        self.panel.Children.Add(Rectangle(
            Width=50,
            Height=50,
            Fill=brush,
            ))

メソッド execute では、選択したファイル内の画像を、パネル panel に追加します。

■ クラス FileClose
class FileClose(Button, Command):         # Command::ConcreteCommand
    def __init__(self, window):
        self.window = window
        self.Content = "Close"
        self.Click += self.execute
    def execute(self, sender, e):
        self.window.Close()

メソッド execute では、ウィンドウを閉じて、アプリケーションを終了させます。


何が問題か:Command パターンを概観する

モジュール CommandToolBar.py は〈GoF〉Command パターンを適用したものです。


WPF コントロールに割当てられたプロバティー(ここでは Click)を介して、イベントハンドラーを起動していると、コマンドとしての独立性が損なわれます。既存のフレームワークに依存するため、柔軟性に優れた拡張が困難になります。そこで、この問題を解消するために、コマンドバインディングを導入します。

Last updated♪09/06/20