前回のあらすじ
Java/Pythonの融合は、Jythonという新たな選択肢を生み出しました。Javaで構築された既存のリソースを再利用できるだけでなく、Javaにはないプログラミングの可能性を拡げます。初心者にプログラムの本質を学ぶ環境を提供するだけでなく、洗練された見通しの良いコードを記述できるとともに、Javaの近未来を予見させます。
前編で、先に示したコードの断片はみな、単純なコードを羅列した一枚岩とでも言うべきものでした。ここからは、役割分担したクラスを導入して、コードの断片が相互に協調しながら複雑な処理を遂行します。全体の世界を把握できるように俯瞰図を示します。
俯瞰図を見ると、アプリケーションに固有の問題領域を表現するモデル(model)、アプリケーションとは独立して再利用可能な部品を提供するコンポーネント(component)群、そして、アプリケーションごとに選択可能な表示系を提供するビュー(view)が、三位一体となって、ひとつのアプリケーションを構成している様を概観できます。
世界の中心でモデルを叫ぶ
最初に、アブリケーションの中核となるモデルを規定します。ここでは、サイクロイドを表現することが目的なので、そのために必要な情報を管理するクラスCycloidを規定します。
from math import *
class Cycloid:
def __init__(self, radius, cycle, step):
self.path = self._path(radius, cycle, step)
self.context = radius, cycle, step
def _path(self, radius, cycle, step):
s = []
for i in range(step+1):
t = i*cycle/step
x = radius*(t-sin(t))
y = radius*(1-cos(t))
s.append((x, y))
return s
def __getitem__(self, index):
return self.path[index]
def xpoints(self):
radius, cycle, step = self.context
return [radius*i*cycle/step for i in range(step+1)]
__init__(self,radius,cycle,step)では、生成したばかりのインスタンスを初期設定します。半径radiusの円が、周期cycleで移動する様子を、分割数stepの精度で再現します。stepの値が大きくなるにつれて、より滑らかなサイクロイド曲線を描きます。radius=2*piとすると、ちょうど一回転します。step=60とすると、円周上を60分割した距離だけ移動するごとに、円周上の定点の軌跡を描きます。
_path(self,radius,cycle,step)では、補助関数として、インスタンス変数pathを初期設定します。与えられた引数radius/cycle/stepを使って、円周上の定点が描く軌跡の座標を列挙したリストを生成します。ここでは、組み込み関数sin/cosを使うので、モジュールmathをimportしておく必要があります。
__getitem__(self,index)では、演算子[]の処理を規定します。index番目の座標値を参照します。Javaの禁じ手、演算子のオーバーロードが可能になります。
xpoints(self)では、円周上の定点が描く軌跡のx座標だけを列挙したリストを生成します。
コンテナ(には愛テム)がなくちゃね
キャンバス内に描く図形要素(コンポーネント)を保持するためには、コンテナが必要です。そこで、任意の図形要素を管理するクラスContainerを規定します。
class Container:
def __init__(self):
self.items = []
def add(self, geometry):
self.items.append(geometry)
def paint(self, g):
for e in self.items:
e.paint(g)
def clear(self):
self.items = []
__init__(self)では、任意の図形要素を保持するコンテナitemsの初期値として、空リスト[]を設定します。
add(self,geometry)では、図形要素geometryをコンテナに追加します。
paint(self,g)では、gを仲介して参照される情報を使って、コンテナ内の図形要素をキャンバスに描きます。
clear(self)では、コンテナに保持された図形要素を、すべて削除します。

