Clean Code - (5) : naming example

­이승환·2021년 11월 11일
0

Clean Code

목록 보기
5/7

의도를 밝히자

  • Bad
const yyyymmdstr = moment().format("YYYY/MM/DD");
  • Good
const currentDate = moment().format("YYYY/MM/DD");

의미있게 구분

  • Bad
getUserInfo();
getClientData();
getCustomerRecord();
  • Good
getUser();

쉽게 검색이 가능하게

  • Bad
// What the heck is 86400000 for?
setTimeout(blastOff, 86400000);
  • Good
// Declare them as capitalized named constants.
const MILLISECONDS_PER_DAY = 60 * 60 * 24 * 1000; //86400000;

setTimeout(blastOff, MILLISECONDS_PER_DAY);

설명가능한 변수

  • Bad
const address = "One Infinite Loop, Cupertino 95014";
const cityZipCodeRegex = /^[^,\\]+[,\\\s]+(.+?)\s*(\d{5})?$/;
saveCityZipCode(
  address.match(cityZipCodeRegex)[1],
  address.match(cityZipCodeRegex)[2]
);
  • Good
const address = "One Infinite Loop, Cupertino 95014";
const cityZipCodeRegex = /^[^,\\]+[,\\\s]+(.+?)\s*(\d{5})?$/;
const [_, city, zipCode] = address.match(cityZipCodeRegex) || [];
saveCityZipCode(city, zipCode);

기억력을 믿지 말자

  • Bad
const locations = ["Austin", "New York", "San Francisco"];
locations.forEach(l => {
  doStuff();
  doSomeOtherStuff();
  // ...
  // ...
  // ...
  // Wait, what is `l` for again?
  dispatch(l);
});
  • Good
const locations = ["Austin", "New York", "San Francisco"];
locations.forEach(location => {
  doStuff();
  doSomeOtherStuff();
  // ...
  // ...
  // ...
  dispatch(location);
});

신중한 메소드나 클래스 이름

  • Bad
function addToDate(date, month) {
  // ...
}

const date = new Date();

// It's hard to tell from the function name what is added
addToDate(date, 1);
  • Good
function addMonthToDate(month, date) {
  // ...
}

const date = new Date();
addMonthToDate(1, date);

종합

//bad
import INVOICE from "../invoices.json";
import PLAYS from "../plays.json";

function statement(invoice, plays) {
  let totalAmount = 0;
  let volumeCredits = 0;
  let result = `청구 내역(고객명: ${invoice.customer})\n`;
  const format = new Intl.NumberFormat("en-US", {
    style: "currency",
    currency: "USD",
    minimumFractionDigits: 2
  }).format;

  for (let perf of invoice.performances) {
    const play = plays[perf.playID]; // object {name, type}
    let thisAmount = 0;
    switch (play.type) {
      case "tragedy": //비극
        thisAmount = 40000;
        if (perf.audience > 30) thisAmount += 1000 * (perf.audience - 30);
        break;
      case "comedy": //희극
        thisAmount = 30000;
        if (perf.audience > 20) thisAmount += 1000 + 500 * (perf.audience - 20);
        thisAmount += 300 * perf.audience;
        break;
      default:
        throw new Error(`알 수 없는 장르: ${play.type}`);
    }
    // 포인트를 적립한다.
    volumeCredits += Math.max(perf.audience - 30, 0);
    // 희극 관객 5명마다 추가 포인트를 제공한다.
    if ("comedy" === play.type) volumeCredits += Math.floor(perf.audience / 5);

    // 청구 내역을 출력한다.
    result += `${play.name}: ${format(thisAmount / 100)} (${
      perf.audience
    }석)\n`;
    totalAmount += thisAmount;
  }
  result += `총액: ${format(totalAmount / 100)}\n`;
  result += `적립 포인트: ${volumeCredits}점\n`;
  return result;
}

statement(INVOICE[0], PLAYS);
import INVOICE from "../../invoices.json";
import PLAYS from "../../plays.json";
import createStatementData from "./createStatementData.js";

function statement(invoice, plays) {
 // 가변데이터로 넘기면 금방 상하기때문에 최대한 불변으로 넘긴다. (굿)
 return renderPlainText(createStatementData(invoice, plays));
}

function renderPlainText(data, plays) {
 let result = `청구 내역(고객명: ${data.customer})\n`;
 for (let perf of data.performances) {
   // 청구 내역을 출력한다.
   result += `${perf.play.name}: ${usd(perf.amount)} (${perf.audience}석)\n`;
 }
 result += `총액: ${usd(data.totalAmount)}\n`;
 result += `적립 포인트: ${data.totalVolumeCredits}점\n`;
 return result;
}

function htmlStatement(invoice, plays) {
 return renderHtml(createStatementData(invoice, plays));
}

function renderHtml(data) {
 let result = `<h1>청구 내역(고객명: ${data.customer})</h1>\n`;
 result += `<table>\n`;
 result += `<tr><th>연극</th><th>좌석 수</th><th>금액</th></tr>`;
 for (let perf of data.performances) {
   // 청구 내역을 출력한다.
   result += `<tr><td>${perf.play.name}</td><td>(${perf.audience}석)</td>`;
   result += `<td>${usd(perf.amount)}</td></tr>\n`;
 }
 result += `</table>\n`;
 result += `총액: ${usd(data.totalAmount)}\n`;
 result += `적립 포인트: ${data.totalVolumeCredits}점\n`;
 return result;
}
function usd(aNumber) {
 return new Intl.NumberFormat("en-US", {
   style: "currency",
   currency: "USD",
   minimumFractionDigits: 2
 }).format(aNumber / 100);
}

document.getElementById("app2").innerText = statement(INVOICE[0], PLAYS);
document.getElementById("app").innerHTML = htmlStatement(INVOICE[0], PLAYS);

<출처 : 리팩터링 2판 (한빛미디어)>
오픈소스 네이밍

profile
Mechanical & Computer Science

0개의 댓글