Python.use(better, anti="GoF") # Let's GoForward《25》Visitor(5)パターン夜明け前★★

《こちらに移動中です》

2007年7月27日 (金)
------------ 序 ------------
GoFデザインパターンは、図らずも Java/C# の脆弱さを露呈する結果となりました。Ruby/Python などより洗練されたオブジェクト指向の支援が得られる環境下では、いくつかのパターンは単純なイディオムに過ぎず、言語によっては組み込みの機能として提 供されているものも珍しくありません。また、GoF の事例を鵜呑みにすると、迂遠なアプローチを余儀なくされるばかりか、Ruby/Python などのより洗練された特徴を活かせません。GoF を模写しても始まりません。GoF が模写したその起源を探ることで、パターンの本質に迫れます。
この連載では、GoF デザインパターンを反面教師として、真のオブジェクト指向の世界を目指す旅へと誘(いざな)います。GoF が何を伝え、何を伝えなかったのか。そのルーツを探ってみると、新たな知見が開けてきます。そろそろ、釈迦の掌(Java/C#)から脱して、天竺(Ruby/Python)へと旅立ちませんか。
Java 原人からホモサピエンスへ:Java/C# から Ruby/Python への進化を望むプログラマーには、ひとつありがちな落とし穴があります。それは、GoF の例題に示してある、Java/C# のために脚色されたフレームワークに追従するあまりに「先祖返り」を余儀なくされ、Ruby/Python の進化した特徴が見過ごされてしまうことです。2011年までに、アナログ放送からディジタル放送への対応に迫られるのと同様に、アナログ思考(Java/C#)からディジタル思考(Ruby/Python)へと、プログラマーの世代交代も加速しつつあります。 さあ、みなさんも取り残されないよう、ただ前進あるのみです。(^_^)
Let's Go Forward ...
ここで公開している記事は「キーワード検索」を利用するための便宜的なものです。詳細は、正式版(PDF)をダウンロードしてご覧ください。
⇒《準備中》
【目次】関連記事
Python/Jython 入門〕Python.use(better, anti="GoF") # Let's GoForward
《査読中》
------------ 本文 ------------

《25》Visitor(5)パターン夜明け前★★

(承前)抽象クラスを導入して、図形要素に共通する特性を抽出します。

class Geometry:
    def __init__(self, drawColor=None, fillColor=None):
        self.drawColor = drawColor
        self.fillColor = fillColor
    def _drawColor(self):
        return (self.drawColor, Color.black)[not self.drawColor]

 抽象クラス Geometry では、子孫クラスに共通する特性として、輪郭を描くときの色 drawColor と、内部を描くときの色 fillColor を規定します。
 メソッド _drawColor は、図形の輪郭を描くときの色を獲得します。キーワード引数 drawColor= を指定すると、その色を使って図形の輪郭を描きます。ただし、この引数を省略すると、その規定値は None となるので、黒 Color.black を使って図形の輪郭を描きます。

class Rectangle(Geometry):
    def __init__(self, x1, y1, x2, y2, 
            drawColor=None, fillColor=None):
        self.origin = x1, y1
        self.corner = x2, y2
        Geometry.__init__(self, drawColor, fillColor)
    def display(self, context):
        cx, cy = self.corner
        x, y = self.origin
        width, height = cx-x, cy-y
        if self.fillColor:
            context.color = self.fillColor
            context.fillRect(x, y, width, height)
        context.color = self._drawColor(context)
        context.drawRect(x, y, width, height)
class Circle(Geometry):
    def __init__(self, x, y, radius, 
            drawColor=None, fillColor=None):
        self.center = x, y
        self.radius = radius
        Geometry.__init__(self, drawColor, fillColor)
    def display(self, context):
        cx, cy = self.center
        r = self.radius
        x, y = cx-r, cy-r
        width = height = 2*r
        if self.fillColor:
            context.color = self.fillColor
            context.fillOval(x, y, width, height)
        context.color = self._drawColor(context)
        context.drawOval(x, y, width, height)

 変更したクラス Rectangle および Circle では、それぞれに固有の特性 origin, corner とともに、どちらにも共通の特性 drawColor, fillColor を初期設定 Geometry.__init__ します。
 メソッド display では、共通の補助関数 _drawColor によって得られた情報をもとに、図形の輪郭を描くときの色を設定します。
《ひよ子のきもち♪2007/07/27》
==================================
河野かえる 著 ◆ 監修:小泉ひよ子とタマゴ倶楽部

Last updated♪2009/07/27