今回扱うリファクタリング
- パラメーターへの代入の除去
- 問い合わせによる一次変数の置き換え
- 委譲の隠蔽
パラメータへの代入の除去
ダメな例
def get_discount_val(input_val,percent):
if input_val > 100:
# × パラメータであるinput_valを直接触っている.
input_val = input_val * percent
else:
input_val = input_val
return input_val
パラメーターへ直接代入している.
他の部分でもinput_valを使う可能性があるため関数のパラメーターを書き換えちゃダメ
良い例
def get_discount_val(input_val,percent):
#input_valをvalueに代入
value = input_val
if value > 100:
# ○ パラメータであるinput_valは直接触れていない.
value = value * percent
else:
value = value
return value
- パラメータを直接触るのではなく変数に代入してから値を操作
- 他の部分でもinput_valを使うことができる.
- 他の部分でもinput_valを使う場合同じように変数に代入する.
内部変数名をvalueにすると引数なのか返り値なのかわかりづらいので
分かりやすい名前にする.↓↓↓↓↓↓↓↓↓↓↓↓↓
もっと良い例 変数をresultに変更する
def get_discount_val(input_val,percent):
if input_val > 100:
result = input_val * percent
else:
result = input_val
return result
できるだけ短くしたいならこっち!
def get_discount_val(input_val,percent):
return input_val * percent if input_val > 100 else input_val
このリファクタリングはとても簡単にできるのでおすすめです!
可読スピードが上がります.
問い合わせによる一次変数の置き換え
一時変数(ローカル変数)が多くてメソッドの抽出が難しい時に使う.
シチュエーション
以下の変数を使って売り上げを計算したい.
売上: salsePrice
量 : quantity
値段: itemPrice
ダメな例
#
double salesPrice = _quantity * _itemPrince
if(salesPrice > 1000):
reuturn salesPrice * 0.95
else:
return salesPrice * 0.90
良い例
# salesPrice()を呼び出す
if(salesPrice() > 1000):
reuturn salesPrice() * 0.95
else:
return salesPrice() * 0.90
def salesPrice():
return _quantity * _itemPrince
メリット
- 他のクラスや関数でsalesPrice()を使いたい場合管理できる.
- もし変数(itemPrice)に変更があった場合アップデートが簡単にできる.
- その変数を関数にすることで一括管理が可能になる.
- ローカル変数を減らす=いいこと
- 一括管理ができる
- 急激な変更が加わった時に管理が簡単
- 関数の引数にも宣言できる
委譲の隠蔽
シチュエーション
- johnという社員の上司の名前を取得したいとする.
- Personクラス とDepartmentクラスがある.
- getDepartment()→所属を返す
- getManager()→マネージャーを返す
ダメな例
jun = Person('jun')
manager1 = Person('manager1')
department = Department(manager1)
jun.setDepartment(department)
manager = john.getDepartment().getManager()
- getDepartment()→Personクラス
- getManager()→Departmentクラス
良い例
# getManager()を新規作成する.
manager = john.getManager()
getManager()→DepartmentクラスからPersonクラスに記述する.
こうすることで
Person→Department→Manager_nameというフローから
Person→Manager_name というフローにできる.
class Person(object):
#Personクラスにマネージャーを呼び出す関数を書く.
def getManager(self):
return _department.getMamager()
class Department(object):
def __init__(self, department_name):
self.department_name = department_name
jun = Person('jun')
manager2 = Person('manager2')
department = Department(manager2)
jun.setDepartment(department)
j_manager = jun.getManager(manager2)
print(j_manager)
#manager2
クラスから呼び出すものが2個以上つながった時はこの手法をとるべき
※ダメな例と良い例と対比させていますがリファクタリングはプログラミングの1つの書き方なので絶対ダメとかではないです。