《Jython2.5》JTree〈GoF〉Iterator が必要に
Java プログラマーのための Python 導入ガイド〈初級/応用編〉《Jython2.5》
JTree〈GoF〉Iterator が必要に
■ 概要
フォルダー/ファイルの階層構造を「簡単に」閲覧できるツールがあると便利です。
この課題では、Swing/GUI を使って階層構造を持つ情報を提示します。〈GoF〉Composite/Iterator/Visitor/Command パターンを導入すると、if/for 文によるコードの汚染、配列の境界問題が解消されるので、要求仕様の変更にも柔軟に対処でき、簡潔で見通しの良いコードを記述できるようになります。
《Note》JPython1.1.x/Jython2.1.x 用に作成したセミナー課題を、Jython2.5 で再構成しました。
事例:コードの解説
次に示すコードの断片はみな、それを実現する手段(how)に依存しています。これを改善して、それで実現したい目的(what)に着目したコードを記述できるようにします。
■ ファイル(フォルダー内)の数
class FileNode(Node): # Composite::Leaf def __len__(self): return 0 class DirNode(Node): # Composite::Composite def __len__(self): return reduce( lambda s,e: s+len(e.userObject)+1,self.treeNode.children(), 0)
■ ファイル(フォルダー内)の合計サイズ
class FileNode(Node): # Composite::Leaf def getsize(self): return getsize(self.path) class DirNode(Node): # Composite::Composite def getsize(self): return reduce( lambda s,e: s+e.userObject.getsize(),self.treeNode.children(), 0)
■ インデント数(ノードの深さ)
メソッド indents を利用すると、各ノードのインデントを返すイテレーターが得られます。
class FileNode(Node): # Composite::Leaf def indents(self, indent=0): return [indent] class DirNode(Node): # Composite::Composite def indents(self, indent=0): return reduce( lambda s,e: s+e.userObject.indents(indent+1),self.treeNode.children(), [indent])
メソッド indents の本体でも、同様に view/DefaultMutableTreeNode と model/Node との相互参照が必要になります。
■ ツリー表示:JTextArea
class FileNode(Node): # Composite::Leaf def textTree(self, indent=0): return ["%s%s%r (%d)"%( self.tab1*(indent-1), self.tab2, self, self.getsize())] class DirNode(Node): # Composite::Composite def textTree(self, indent=0): return reduce( lambda s,e: s+(e.userObject.textTree(indent+1)),self.treeNode.children(), ["%s%s%r"%( self.tab1*(indent-1), self.tab2*(not not indent), self)])
■ 前順走査
class FileNode(Node): # Composite::Leaf def preorder(self): return [self] class DirNode(Node): # Composite::Composite def preorder(self): return reduce( lambda s,e: s+e.userObject.preorder(),self.treeNode.children(), [self])
メソッド preorder の本体では、ビュー DefaultMutableTreeNode から得られる子ノード treeNode.children の情報をもとに、各ノードから e.userObject よって、再びモデル Node を参照しています。
何が問題か
これらの事例は「copy&paste の弊害」と同じ病巣を抱えています。このセミナー課題では、5つの場合を挙げていますが、実際のアプリケーション開発では、数多の場合に対処する必要が生じます。このアプローチを踏襲するかぎり「数多の似て非なるコードを書く」という呪縛を解く術がありません。
Tips
》作業中です《