Open2

マーチン・ファウラーのリファクタリングの呼吸

ピン留めされたアイテム
上かるび上かるび

序章

何回か読んでいるが、いざ自分でリファクタリングしようとしたときに思い出せなかったり理解できていなかったりするので、具体的なコード例をTypeScriptベースでドキュメントとして残していく。

上かるび上かるび

ステートメントのスライド

before

ts
// ❌ 関連の弱い並び・宣言が使う位置から遠い
const pricingPlan = retrievePricingPlan();
const order = retreiveOrder();
let charge;
const chargePerUnit = pricingPlan.unit;

after

ts
// ✅ 関連の強い並びに寄せる・宣言は使用直前
const pricingPlan = retrievePricingPlan();
const chargePerUnit = pricingPlan.unit;
const order = retrieveOrder();
let charge: number;

サンプル

並べ方の原則

  • 同じオブジェクトへのアクセスは固める (plan.* ブロック、order.* ブロック)
  • 計算は最後に
  • 関数抽出の前段として、依存の境界が見える並びにしておく
ts
type PricingPlan = {
  id: string;
  unit: number; // 単価
  currency: 'JPY' | 'USD';
};

type Order = {
  id: string;
  quantity: number;
};

function retrievePricingPlan(): PricingPlan {
  // 実装はダミー
  return { id: 'basic', unit: 1200, currency: 'JPY' };
}

function retrieveOrder(): Order {
  // 実装はダミー
  return { id: 'ORD-001', quantity: 3 };
}

function calcCharge(plan: PricingPlan, order: Order): number {
  // 1) plan に連なるデータアクセスをまとめる
  const unitPrice = plan.unit;

  // 2) order に連なるデータアクセスをまとめる
  const qty = order.quantity;

  // 3) 依存しない計算は最後にまとめる
  const charge = unitPrice * qty;
  return charge;
}

const plan = retrievePricingPlan();
const order = retrieveOrder();

// 使う直前で宣言・初期化
const charge = calcCharge(plan, order);
console.log({ charge });

関数抽出するなら

ts
function unitPriceFrom(plan: PricingPlan): number {
  return plan.unit;
}

function quantityFrom(order: Order): number {
  return order.quantity;
}

function calcCharge(plan: PricingPlan, order: Order): number {
  const unitPrice = unitPriceFrom(plan);
  const qty = quantityFrom(order);
  return unitPrice * qty;
}