SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

よろずプログラマーのためのPython導入ガイド

Java meets Python - 第0回 Jythonはじめました(後編)

よろずプログラマーのためのPython導入ガイド (2)


  • X ポスト
  • このエントリーをはてなブックマークに追加

世界の中心でコンポーネントを叫ぶ

 キャンバスに表示したい図形要素(コンポーネント)は、他のアブリケーションでも再利用します。そこで、クラスGeometryの傘下に、種々の部品群を規定します。

class Geometry:
    drawColor = Color.black
    fillColor = Color.white
    def __init__(self, drawColor, fillColor=None):
        if drawColor:
            self.drawColor = drawColor
        self.fillColor = fillColor
    def transfer(self, context, p):
        ox, oy, kx, ky = context
        x, y = p
        return ox+int(kx*x), oy-int(ky*y)

 クラスGeometryは、すべての幾何図形に共通する特性を規定します。

class Circle(Geometry):
    def __init__(self,
            center, radius, drawColor=None, fillColor=None):
        Geometry.__init__(self, drawColor, fillColor)
        self.center = center
        self.radius = radius
    def paint(self, g):
        x, y = self.center
        r = self.radius
        cx, cy, d = x-r, y-r, 2*r
        if self.fillColor:
            g.color = self.fillColor
            g.fillOval(cx, cy, d, d)
        g.color = self.drawColor
        g.drawOval(cx, cy, d, d)
    def transform(self, context):
        ox, oy, kx, ky = context
        return Circle(
            (self.transfer(context, self.center)), ky*self.radius, 
            self.drawColor, self.fillColor)

 クラスCircleは、円に固有の特性を規定します。

class Dot(Circle):
    def transform(self, context):
        return Circle(
            (self.transfer(context, self.center)), self.radius, 
            self.drawColor, self.fillColor)

 クラスDotは、点(小円)に固有の特性を規定します。

class Line(Geometry):
    def __init__(self, start, end, drawColor=None):
        Geometry.__init__(self, drawColor)
        self.start = start
        self.end   = end
    def paint(self, g):
        g.color = self.drawColor
        x1, y1 = self.start
        x2, y2 = self.end
        g.drawLine(x1, y1, x2, y2)
    def transform(self, context):

        start = self.transfer(context, self.start)
        end   = self.transfer(context, self.end)
        return Line(start, end, self.drawColor)

 クラスLineは、直線に固有の特性を規定します。

class Polyline(Geometry):
    def __init__(self, points, drawColor=None):
        Geometry.__init__(self, drawColor)
        self.points = points
    def paint(self, g):
        g.color = self.drawColor
        g.drawPolyline(
            [x for x, y in self.points], 
            [y for x, y in self.points], len(self.points))
    def transform(self, context):
        s = []
        for e in self.points:
            s.append(self.transfer(context, e))
        return Polyline(s, self.drawColor)

 クラスPolylineは、折れ線に固有の特性を規定します。

世界の中心でビューを叫ぶ

 アブリケーションを実行する準備が整いました。ここまで作成したコードの断片は、クラス単位で再利用できます。以下のコードを実行すると、その動作を確認できます。

def paint(g):
    CanvasPanel.paint(panel, g)
    container.paint(g)
panel = CanvasPanel()
panel.paint = paint

step, seconds = 60, 0.05
container = Container()
radius, R = 10, 3
cycloid = Cycloid(radius, 2*pi, step)
xpoints = cycloid.xpoints()
context = 50, 70, 3, 3

def animate(e):
    for i in range(step+1):
        sleep(seconds)
        container.clear()
        e = Line((xpoints[i], radius), cycloid[i])
        container.add(e.transform(context))
        e = Circle((xpoints[i], radius), radius, Color.blue)
        container.add(e.transform(context))
        e = Polyline(cycloid[:i+1], Color.red)
        container.add(e.transform(context))
        e = Dot(cycloid[i], R, Color.red, Color.yellow)
        container.add(e.transform(context))
        panel.paintImmediately(bounds)

button = JPanel(layout=GridLayout(1, 0))
button.add(JButton("animate", actionPerformed=animate))

bounds = Rectangle(0, 0, 360, 100)
frame = JFrame(defaultCloseOperation=JFrame.EXIT_ON_CLOSE, 
    bounds=bounds, title="Cycloid", layout=BorderLayout())
frame.add(panel, BorderLayout.CENTER)
frame.add(button, BorderLayout.WEST)
frame.visible = True

 関数animateでは、ボタン[animate]を押したときに、panel内に描かれる図形を規定します。サイクロイドを描くときに、円周上の定点が描く軌跡をアニメーション効果を使って表現します。

 関数animateの役割は、Cycloid/Container/Geometryを仲介することです。Cycloidは、専門領域の知識の他に、アブリケーションに依存する情報を保持しています。Containerは、任意の図形Geometryを追加(add)した後で、ウィンドウ内に表示(paint)します。Geometryは、Line(直線)、Circle(円)、Polyline(折れ線)、Dot(点)に共通する特性を規定します。

 ここで注目して欲しいのは、Cycloidは、専門領域の知識とアブリケーションに依存する情報とを、分割統治する必要があることです。専門領域の知識がない開発者には、アブリケーションを開発するのに必要な情報だけを提示します。なぜなら、開発者は、その数学的な背景を知らなくても、任意の図形をいつどこに表示するかだけを理解できればいいからです。こうして、専門家と開発者とは、相手の専門領域(自分には未知の領域)に立ち入らずに、分業化が可能になります。

 このようにして、サイクロイドという専門領域の問題も、アブリケーション開発者には、単にウィンドウ内に図形を描くという一般領域の問題へと帰着します。

世界の中心で何を叫ぶ?

 アジァイル開発の現場では、分業化が進んでいます。分析チーム、設計チームなど、親請け下請けという従来型の上下関係ではなく、分業化された専門家集団(マトリックス型組織)が形成されます。プログラミングチームも、コンポーネント開発グルーブ、モデル開発グルーブのように分割統治が徹底されています。そのようなグループ間では「コンポーネントはまだか」「モデルはどうした」という叫びが聞こえてきます。

次のページ
Java/C#の常識はOOPの非常識《予告編》

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
よろずプログラマーのためのPython導入ガイド連載記事一覧

もっと読む

この記事の著者

小泉ひよ子とタマゴ倶楽部(コイズミヒヨコトタマゴクラブ)

http://tamago-club.cocolog-nifty.com/「楽しくなければ仕事じゃない」が私たちのモットー。99%の苦悩の連続も、1%の成功に報われます。だからこそ、この仕事が楽しくて仕方がないのです。楽をするための努力なら惜しみません。何もせず楽をしているのと、努力をしたから楽ができるのと...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/1727 2007/10/24 19:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング