0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【リファクタリングカタログ】関数宣言の変更

Last updated at Posted at 2020-12-23

書籍 リファクタリング―既存のコードを安全に改善する 第2版

またはWeb版(の方が完全版なんですが)には、
これを補完する リファクタリングカタログ が公開されています

これは何

書籍およびカタログはサンプルコードが JavaScript です、
カタログをもとに Python でリファクタリングのサンプルコードを示します

詳細解説は本にお任せして、「ここをこうこうこう」くらいのノリで示します

カタログ:Change Function Declaration

当初コード、JavaScript版
function circum(radius) {
  return 2 * Math.PI * radius;
}
リファクタリング後
function circumference(radius) {
  return 2 * Math.PI * radius;
}

Python版

当初コード
import numpy as np
def circum(radius):
  return 2 * np.pi * radius

テストコード

テストコード、三角測量
from unittest import TestCase
import numpy as np
class TestCatalog(TestCase):
  def test_circum_10(self):
    self.assertEqual(circum(10), 20*np.pi)
  def test_circum_20(self):
    self.assertEqual(circum(20), 40*np.pi)

ここをこうこうこう

内部関数を追加
import numpy as np
def circum(radius):
  def circumference(radius): # add
    return 2 * np.pi * radius # add
  return 2 * np.pi * radius
内部関数を利用する
import numpy as np
def circum(radius):
  def circumference(radius):
    return 2 * np.pi * radius
  return circumference(radius) # edit
関数を外部化、変数を抽出
import numpy as np
def circum(radius):
  return circumference(radius)
def circumference(radius): # move
  return 2 * np.pi * radius # move
テストの対象を変更
from unittest import TestCase
import numpy as np
class TestCatalog(TestCase):
  def test_circum_10(self):
    self.assertEqual(circumference(10), 20*np.pi) # edit
  def test_circum_20(self):
    self.assertEqual(circumference(20), 40*np.pi) # edit
未使用関数を除去
import numpy as np
def circumference(radius):
  return 2 * np.pi * radius

出来上がり

この例のような変更はエディタのリファクタリング機能が助けてくれることもあると思います、
引数の追加、除去も同様の手順で安全にリファクタリングできます

引数の変更の例

オブジェクトの一部だけ使うのに、引数ではオブジェクト丸ごと渡しているのを是正したいケース

当初コード、JavaScript版
function inNewEngland(aCustomer) {
  return ["MA", "CT", "ME", "VT", "NH", "RI"].includes(aCustomer.address.state);
}
リファクタリング後
function inNewEngland(stateCode) {
  return ["MA", "CT", "ME", "VT", "NH", "RI"].includes(stateCode);
}

Python版

当初コード
def inNewEngland(aCustomer):
  return aCustomer.address.state in ["MA", "CT", "ME", "VT", "NH", "RI"]

テストコード

テストコード
from unittest import TestCase
from collections import namedtuple
class TestCatalog(TestCase):
  def test_inNewEngland(self):
    address = namedtuple("address", "state")
    aCustomer = namedtuple("aCustomer", "address")
    customer = aCustomer(address("MA"))
    self.assertTrue(inNewEngland(customer))

ここをこうこうこう

変数の抽出
def inNewEngland(aCustomer):
  stateCode = aCustomer.address.state # add
  return stateCode in ["MA", "CT", "ME", "VT", "NH", "RI"] # edit
関数の抽出
def inNewEngland(aCustomer):
  stateCode = aCustomer.address.state
  return xxinNewEngland(stateCode) # edit
def xxinNewEngland(stateCode): # add
  return stateCode in ["MA", "CT", "ME", "VT", "NH", "RI"] # add
変数のインライン化
def inNewEngland(aCustomer):
  return xxinNewEngland(aCustomer.address.state) # edit
def xxinNewEngland(stateCode):
  return stateCode in ["MA", "CT", "ME", "VT", "NH", "RI"]
テストの対象を変更
from unittest import TestCase
from collections import namedtuple
class TestCatalog(TestCase):
  def test_inNewEngland(self):
    address = namedtuple("address", "state")
    aCustomer = namedtuple("aCustomer", "address")
    customer = aCustomer(address("MA"))
    self.assertTrue(xxinNewEngland(customer.address.state)) # edit
未使用関数を除去、そして、関数名の変更
def inNewEngland(stateCode):
  return stateCode in ["MA", "CT", "ME", "VT", "NH", "RI"]

出来上がり

最後ちょっとジャンプしましたが、関数名の変更はエディタの機能が助けてくれると期待します

以上

参考

(Youtube)マーチンファウラーによろしく - リファクタリングカタログ - 関数宣言の変更 @ Tommy109

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?