《37》リファクタリング:第3のメソッド〈Python 2.x 版〉

実録:はじめてのプログラミング記事一覧
《37》リファクタリング:第3のメソッド

《著》小粒ちゃん+α《監修》小泉ひよ子とタマゴ倶楽部
2009年3月5日(木)

今日の進捗

  • Language Reference: Numeric and Mathematical Modules; functools — Higher order functions and operations on callable objects
  • Python.use(better) -- セミナー研修テキスト
  • 連結リスト課題を「続・ひよ子のきもち」で公開
Comment
本人:野中 新しいメソッドを追加するときにはリファクタリングの効果を実感できますね。
担当:伊藤/本間 。(^^)

何が問題か:第3のメソッド

メソッド pop も(前述した)2つのメソッド __delitem__/remove とよく似ています。

    def pop(self):
        prev,node = self.head,self.head.next
        while node:
            if node==self.tail:
                value = node.item
                self.tail = prev
                prev.next = node.next
                del node
                return value
            prev,node = node,node.next
        else:
            s = self.__class__.__name__
            raise IndexError,"pop from empty %s"%s

(強調した部分を除いて)その大半が同じなのが分かります。これも他のメソッドのように要素を削除するのは共通なので、そのコードが重複するのも自然です。そこで、同様のリファクタリングを実施します。

リファクタリング:第3のメソッド

リファクタリングを実施して、これらの異なるコードの断片を抽出して、独立したメソッドを用意します。このとき、もとの局所変数を、新たに引数として再定義します。

    def _removeNode_pop_cond(self, node, value, n):
        return node==self.tail
    def _removeNode_pop(self, prev, node):    # ----- before
        value = node.item
        self.tail = prev
        prev.next = node.next
        del node
        return value
    def _removeNode_pop_error(self, s):
        raise IndexError,"pop from empty %s"%s

しかし、まだ問題が残ります。それは、メソッド _removeNode_pop の本体が

    def _removeNode_body(self, prev, node):
        prev.next = node.next
        del node
        return ...

メソッド _removeNode_body の本体とは似て非なることです。そこで、pop にも対処できるように、

class myList(object):
    def _removeNode_body(self, prev, node, value=None):
        prev.next = node.next
        del node
        return value
    def _removeNode_pop(self, prev, node):    # ----- after
        self.tail = prev
        return self._removeNode_body(prev, node, node.item)

メソッド _removeNode_body には、新たな引数 value を導入します。また、メソッド _removeNode_pop の本体では、このメソッドを再利用するとともに、その結果をリターン値にすることで、局所変数 value を割愛できます。すると、3つのメソッド __delitem__/remove/pop のすべてに対処できるようになります。

Tips

Last updated♪09/03/05