《34》リファクタリング:重複するコードの断片〈Python 3.0 版〉

記事一覧

実録:はじめてのプログラミング
リファクタリング:重複するコードの断片

《著》小粒ちゃん+α《監修》小泉ひよ子とタマゴ倶楽部
第3版♪2009/02/28 ● 2009年3月2日(月)

■ 概要

重複するコードの断片から、新たなメソッドを抽出します。

 リファクタリングが困難なときには「組み込み関数 eval を利用できないか」を検討します。
 すると、新たなメソッドを抽出して、より洗練されたコードを記述できるようになります。

何が問題か:重複するコードの断片

すでに紹介したメソッドには、コードの断片が重複するものがあります。たとえば、次に示す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〕と同様に「共通項を括り出して」簡潔で見通しの良いコードを目指します。
まず、既存のメソッド __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 ...

共通するブロック本体から、独立したメソッド _removeNode_body を抽出します。このとき、もとの局所変数 prev/node を、新たに引数として再定義します。

Tips

TOP