《34》リファクタリング:重複するコードの断片 〈Python 2.x 版〉
実録:はじめてのプログラミング《記事一覧》
《34》リファクタリング:重複するコードの断片
《著》小粒ちゃん+α《監修》小泉ひよ子とタマゴ倶楽部
2009年3月2日(月)
関連記事
今日の進捗
- Language Reference: Numeric and Mathematical Modules; functools — Higher order functions and operations on callable objects
- Python.use(better) -- セミナー研修テキスト
- 連結リスト課題を「続・ひよ子のきもち」で公開
Comment | |
---|---|
本人:野中 | やっとリファクタリングとメタプログラミングが一緒になった感じがします。 |
担当:伊藤/本間 | 。(^^) |
何が問題か:重複するコードの断片
すでに紹介したメソッドを見ると、重複するコードの断片が少なくありません。たとえば、次に示す2つのメソッドでは、
def __delitem__(self, key): prev,node = self.head,self.head.next n = 0 while node: if n==key: prev.next = node.next del node break prev,node = node,node.next n += 1 else: s = self.__class__.__name__ raise IndexError,"%s assignment index out of range"%s def remove(self, value): prev,node = self.head,self.head.next while node: if node.item==value: prev.next = node.next del node break prev,node = node,node.next else: s = self.__class__.__name__ raise ValueError,"%s.remove(x): x not in %s"%(s,s)
(強調した部分を除いて)その大半が同じなのが分かります。実際に、どちらのメソッドも要素を削除するのは共通なので、そのコードが重複するのも自然です。そこで、リファクタリングを実施して、これらの重複するコードの断片を抽出して、独立したメソッドを用意します。
リファクタリング:重複するコードの断片
リファクタリングの基本は「整理整頓」です。それには、因数分解〔factorization〕と同様に、共通項を括り出してそれらを削除することで、簡潔で見通しの良いコードになることを目指します。
まず、2つのメソッド __delitem__/remove に共通するメソッド removeNode を抽出することから始めます。そこで、if に続くブロックに着目すると、
class myList(object): def removeNode(self, value): prev, node = self.head, self.head.next n = 0 while node: if ...: # (1) return self._removeNode_body(prev, node) prev, node = node, node.next n += 1 else: s = self.__class__.__name__ raise ... # (2) def _removeNode_body(self, prev, node): prev.next = node.next del node return ...
2つの条件式に違いはあっても、ブロック本体は同じなのが分かります。そこで、共通するブロック本体を独立したメソッド _removeNode_body として抽出します。このとき、もとの局所変数 prev/node は、新たに引数として再定義されます。
Tips
Last updated♪09/03/03