Python.use(better, follow=”K&R”) リファクタリング 6/10
《Previous|6/10|Next》
Python.use(better, follow=”K&R”) # for novice 《記事一覧》
リファクタリング:クラス固有の処理
[Python]何が問題か?
#------ before --------------------------------
class HashTable:
def __getitem__(self, key):
e = self._detect(key)
if e:
return e[key] # NOTICE !!
else:
raise KeyError, keyclass Tnode(BinTree):
def __getitem__(self, key):
e = self._detect(key)
if e:
return e.count # NOTICE !!
else:
raise KeyError, key
2つクラス HashTable/Tnode において、メソッド __getitem__ の本体を見ると、その違いは return に続く箇所だけだと分かります。そこで、これらの異なるコードの断片から共通する構造を抽出して、それを再利用可能とするために、リファクタリングを履行します。
[Python]ある解決法
リファクタリングを履行すると、次のように、コードの見通しが良くなり、その保守も容易になります。
共通する処理(テンプレート)_toget と、クラスごとに固有の処理(名前は同じでも、本体が異なる)_valueItem とを分割統治します。
class eXdict:
def _valueItem(self, e, key): raise NotImplementedError
メソッド _valueItem が例外 NotImplementedError を生成します。これは、子孫クラスにおいて、このメソッドを再定義する必要があることを意味します。
class HashTable(eXdict):
def _valueItem(self, e, key): return e[key]
演算子 e[key] を適用して得られるものをリターン値とします。
class Tnode(BinTree):
def _valueItem(self, e, key): return e.count
インスタンス属性 e.count を参照して得られるものをリターン値とします。
# cz_08.py -------------------------------------------- after ---
class eXdict:
def _toget(self, key, func):
e = self._detect(key)
if e:
return self._valueItem(e, key)
else:
return eval("self._%s(key)"%func)
リファクタリング後のメソッド _toget は、以前の __getitem__ に取って代わるもので、return に続く箇所を、先に定義したメソッド呼び出し _valueItem に統一しています。