Posts jest
Post
Cancel

jest

1
2
3
4
5
6
7
8
9
function priceOrder(product, quantity, shippingMethod) {
  const basePrice = product.basePrice * quantity;
  const discount = Math.max(quantity - product.discountThreshold, 0 )
  					* product.basePrice * product.discountRate;
  const shippingPerCase = (basePrice > shippingMethod.discountThreshold) ? shippingMethod.discountedFee : shippingMethod.feePerCase;
  const shippingCost = quantity * shippingPerCase;
  const price = basePrice - discount + shippingCost;
  return price;
}
  1. 먼저 배송비 계산 부분을 함수로 추출한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
function priceOrder(product, quantity, shippingMethod) {
  const basePrice = product.basePrice * quantity;
  const discount = Math.max(quantity - product.discountThreshold, 0 )
  					* product.basePrice * product.discountRate;
  const price = applyShipping(basePrice, shippingMethod, quantity, discount);
  return price;
}

function applyShipping(basePrice, shippingMethod, quantity, discount) {
  const shippingPerCase = (basePrice > shippingMethod.discountThreshold) ? shippingMethod.discountedFee : shippingMethod.feePerCase;
  const shippingCost = quantity * shippingPerCase;
  const price = basePrice - discount + shippingCost;
  return price;
}
  1. 첫 번째 단계와 두 번째 단계가 주고받을 중간 데이터 구조를 만든다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function priceOrder(product, quantity, shippingMethod) {
  const basePrice = product.basePrice * quantity;
  const discount = Math.max(quantity - product.discountThreshold, 0 )
  					* product.basePrice * product.discountRate;
  const priceData = {basePrice: basePrice, quantity: quantity, discount:discount};
  const price = applyShipping(priceData, shippingMethod);
  return price;
}

function applyShipping(priceData, shippingMethod) {
  const shippingPerCase = (priceData.basePrice > shippingMethod.discountThreshold) ? shippingMethod.discountedFee : shippingMethod.feePerCase;
  const shippingCost = priceData.quantity * shippingPerCase;
  const price = priceData.basePrice - priceData.discount + shippingCost;
  return price;
}
  1. 첫 번째 단계 코드를 함수로 추출
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function priceOrder(product, quantity, shippingMethod) {
   const priceData = calculatePricingData(product, quantity)
  return applyShipping(priceData, shippingMethod);;
}

function calculatePricingData(product, quantity) {
  const basePrice = product.basePrice * quantity;
  const discount = Math.max(quantity - product.discountThreshold, 0 )
  					* product.basePrice * product.discountRate;
  return {basePrice: basePrice, quantity: quantity, discount:discount};
}

function applyShipping(priceData, shippingMethod) {
  const shippingPerCase = (priceData.basePrice > shippingMethod.discountThreshold) ? shippingMethod.discountedFee : shippingMethod.feePerCase;
  const shippingCost = priceData.quantity * shippingPerCase;
  return  priceData.basePrice - priceData.discount + shippingCost;
}

명령줄 프로그램 쪼개기(자바)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public static void main(String[] args) {
  try {
    if (args.length == 0) throw new RuntimeException("파일명을 입력하세요.");
    String fileName = args[args.length - 1];
    File input = Paths.get(filename).toFile();
    ObjectMapper mapper = new ObjectMapper();
    Order[] orders = mapper.readValue(input, Order[].class);
    if (System.of(args).anyMatch(arg -> "-r".equals(args)))
      System.out.println(System.of(orders)
                         .filter(o -> "ready".equals(o.status))
                         .count());
    else
      System.out.println(orders.length);
  } catch (Exception e) {
    System.err.println(e);
    System.exit(1);
  }
}
  1. Run 메서드를 테스트 코드에서 쉽게 호출할 수 있도록 접근 범위를 패키지로 설정
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public static void main(String[] args) {
  try {
    System.out.println(run(args));
  } catch (Exception e) {
    System.err.println(e);
    System.exit(1);
  }
}

static void run(String[] args) throw IOException {
  if (args.length == 0) throw new RuntimeException("파일명을 입력하세요.");
  String filename = args[args.length - 1];
  File input = Paths.get(filename).toFile();
  ObjectMapper mapper = new ObjectMapper();
  Order[] orders = mapper.readValue(input, Order[].class);
  if (Stream.of(args).anyMatch(arg -> "-r".equals(arg)))
    return System.of(orders)
                       .filter(o -> "ready".equals(o.status))
                       .count();
  else
    return orders.length;
}
  1. 코드를 독립된 메서드로 추출
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
static long run(String[] args) throws IOException {
  if (args.length == 0) throw new RuntimeException("파일명을 입력하세요");
  String filename = args[args.length - 1];
  return countOrders(args, filename);
}

private static long countOrders(String[] args, String filename) throws IOException {
  File input = Paths.get(filename).toFile();
  ObjectMapper mapper = new ObjectMapper();
  Order[] orders = mapper.readValue(input, Order[].class);
  if (Stream.of(args).anyMatch(arg -> "-r".equals(arg)))
    return Stream.of(orders).filter(o -> "ready".equals(o.status)).count();
  else
    return orders.length;
}
  1. 다음으로 중간 데이터 구조를 추가한다. 레코드는 단순한 게 좋은데, 자바이므로 클래스로 구현한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
static long run(String[] args) throws IOException {
  if (args.length == 0) throw new RuntimeException("파일명을 입력하세요.");
  CommandLine commandLine = new CommandLine();
  String filename = args[args.length - 1];
  return countOrders(commandLine, args, filename);
}

private static long countOrders(CommandLine commandLine, String[] args, String filename)
  throws IOException {
  File input = Paths.get(filename).toFile();
  ObjectMapper mapper = new ObjectMapper();
  Order[] orders = mapper.readValue(input, Order[].class);
  if (Stream.of(args).anyMatch(org -> "-r".equals(arg)))
    return Stream.of(orders).filter(o -> "ready".equals(o.status)).count();
  else
    return orders.length;
}

private static class CommandLine {}
This post is licensed under CC BY 4.0 by the author.