Python 弾丸ツアー /Java: JavaBeans 準拠 ... step 2: キーワード引数

OOPデザインパターンリファクタリング

Python.use(better); Python 弾丸ツアー /Java: JFC/Swing 編
>>> JavaBeans 準拠
step 2: キーワード引数
《Python3.1|Jython2.5|IronPython2.6》

《著》小粒ちゃん@湘南組《監修》小泉ひよ子とタマゴ倶楽部
第0版♪2001/03/02 ● 第1版♪2003/05/23 ● 第4版♪2010/03/08

step 2: ボタンを利用する

■ キーワード引数

 ̄キーワード引数を利用すると、クラス呼び出しのときに、必要な属性を初期設定できます。たとえば、

    ## ---------------------------------------- step3
    class Tips(JPanel):
        def __init__(self, *args, **keys):
            button = JButton(
                text = "Click Me",
                preferredSize = (200, 50),
                actionPerformed = self.actionPerformed,
                )
            self.add(button)

        def actionPerformed(self, e):       # ActionListener
            comp = e.source
            comp.text = "%s"%ctime()

    def tips():
        frame = JFrame(
            title = "Timer",
            defaultCloseOperation = JFrame.EXIT_ON_CLOSE,
            )
        comp = Tips()
        frame.contentPane = comp
        frame.pack()
        frame.visible = True

    tips()

step2 では、インスタンス button を生成した後で、プロパティー .actionPerformed を利用して、リスナー self.actionPerformed を登録していましたが、

    ## ---------------------------------------- step2
            button = JButton()
            ...
            button.actionPerformed = self.actionPerformed

step3 では、キーワード引数 actionPerformed= を利用すると、インスタンス button を生成するとともに、リスナー self.actionPerformed を初期設定できます。

    ## ---------------------------------------- step3
            button = JButton(
                ...
                actionPerformed = self.actionPerformed,

《Point》大域変数と鋏は使いよう:プログラムにとって大域変数は厄介な存在ですが、これがプログラミングになると大域変数は重宝します。

    def tips():
        frame = JFrame(
            title = "Timer",
            defaultCloseOperation = JFrame.EXIT_ON_CLOSE,
            )
        comp = Tips()
        frame.contentPane = comp
        frame.pack()
        frame.visible = True
        pass                    ; global Qtips3; Qtips3 = comp

ここでは、クラス Tips のインスタンス comp を生成した後で、それを大域変数 Qtips3 を介して、いつでも参照できるようにしています。その行を pass で始めたのは、プログラマーの喚起を促すためです(些細なことですが、"; global" など、滅多にないコードの断片を頼りにすると、検索するときに便利です。動作を確認した後で不要になっても、削除せずにコメント行にして残しておきます)。アプリケーションを起動するときに、

$ jython -i swingTimer.py
...
    
オプション -i を指定したのはこのためです。前述した事例では、不正アクセスとして、
>>> Qtips3.add(JButton("oops"))
意味のないボタンを追加できる「抜け道」が、クラス Tips のインスタンスには存在することを確認しました。これには「功罪」2つの側面があります。たとえば、アプリケーションを実行中に、その状態を変更したり、コードを改良してすぐに、その動作をその場で確認できる術があると便利です。たとえば、次のようにすると、
>>> def oops(e):
...     comp = e.source
...     comp.text = ")x_x( ... too bad"
... 
>>> comp = Qtips3.components[0]
>>> comp.actionPerformed = oops
ボタンをクリックしたときの動作を変更できます。要求仕様が曖昧であったり、実際に運用してみないと分からない機能などを模索したいときには、とても重宝します。アジャイル開発では(コインの裏表のように)設計とプログラミングとが同時進行する状況下にあるので、この支援機能が不可欠です。

TOP
》作業中です《