2-3
意味のまとまりでメソッド化
計算ロジックをベタ書きで並べると、処理の切れ目をコメントで区切りたくなる。コメントで区切りたくなったらそこが関数抽出のサインだ。意味のまとまりごとに関数へ切り出して名前を付ければ、メインの処理は「何を順にやるか」だけを語る目次になり、各ステップは単体でテストできる。
請求額計算のステップを関数に分ける
✕ Bad
def calc_billing_amount(
advisory_fee: int,
bookkeeping_fee: int,
year_end_fee: int,
advance_received: int,
) -> int:
# 役務の税抜合計
subtotal = advisory_fee + bookkeeping_fee + year_end_fee
# 消費税を加算
total_with_tax = subtotal + subtotal * 10 // 100
# 源泉所得税(報酬の10.21%)を控除
after_withholding = total_with_tax - subtotal * 1021 // 10000
# 前受金を充当
return max(after_withholding - advance_received, 0)✓ Good
def sum_service_fees(advisory: int, bookkeeping: int, year_end: int) -> int:
return advisory + bookkeeping + year_end
def add_consumption_tax(subtotal: int) -> int:
return subtotal + subtotal * 10 // 100
def deduct_withholding_tax(amount: int, subtotal: int) -> int:
return amount - subtotal * 1021 // 10000
def offset_advance_received(amount: int, advance_received: int) -> int:
return max(amount - advance_received, 0)
def calc_billing_amount(
advisory_fee: int,
bookkeeping_fee: int,
year_end_fee: int,
advance_received: int,
) -> int:
subtotal = sum_service_fees(advisory_fee, bookkeeping_fee, year_end_fee)
with_tax = add_consumption_tax(subtotal)
after_withholding = deduct_withholding_tax(with_tax, subtotal)
return offset_advance_received(after_withholding, advance_received)源泉徴収率の改定や税率変更があっても、直す関数は1つだけ。各関数は引数 → 戻り値だけで完結する純粋関数なので、境界値のテストも書きやすい。