카테고리 없음

[TIL] JAVA CH2 커머스 STEP2

mooncommit 2026. 3. 27. 21:41

📅 2026.03.27

오늘 한 일

오늘 커머스 플랫폼 STEP2를 완료했다!

STEP2의 핵심은 객체 지향 설계를 적용해서 Main에 몰려있던 로직을 CommerceSystem 클래스로 분리하는 것이었다.


STEP1 → STEP2 무엇이 달라졌나?

STEP1 구조

Main.java
Product.java

Main 안에 while문, for문, 입력 처리까지 전부 다 있었다.

STEP2 구조

Main.java
Product.java
CommerceSystem.java  ← 새로 추가!

Main은 상품 목록 설정 + CommerceSystem 객체 생성만 담당하고,
실제 실행 로직은 CommerceSystemstart() 메서드가 맡는다.


오늘 작성한 코드

Product.java — 변경 없음

어제 STEP1에서 만든 코드 그대로다. 상품 하나의 데이터를 담는 클래스.
속성에 private이 붙어 있어서 외부에서 직접 접근 못 하고 Getter로만 꺼낼 수 있다.

public class Product {
    private String name;
    private int price;
    private String explain;
    private int count;

    public Product(String name, int price, String explain, int count) {
        this.name = name;
        this.price = price;
        this.explain = explain;
        this.count = count;
    }

    public String getName() { return name; }
    public int getPrice() { return price; }
    public String getExplain() { return explain; }
    public int getCount() { return count; }
}

CommerceSystem.java 

Main에서 관리하던 while문 + 입력 처리를 start() 메서드로 옮겼다.
productListscanner는 생성자를 통해 Main에서 주입받는 구조다.

import java.util.List;
import java.util.Scanner;

public class CommerceSystem {

    // 속성
    private List<Product> productList;
    private Scanner scanner;

    // 생성자
    public CommerceSystem(List<Product> productList, Scanner scanner) {
        this.productList = productList;
        this.scanner = scanner;
    }

    // 기능
    public void start() {
        while (true) {

            int count = 1;
            System.out.println("[ 실시간 커머스 플랫폼 - 전자제품 ]");
            for (Product product : productList) {
                System.out.println(count + ". " + product.getName() + " | "
                    + product.getPrice() + "원 | " + product.getExplain()
                    + " | " + product.getCount());
                count++;
            }

            System.out.println("0. 종료 | 프로그램 종료");
            System.out.print("입력 : ");

            int exit = scanner.nextInt();
            if (exit == 0) {
                System.out.println("------------------");
                System.out.println("커머스 플랫폼을 종료합니다.");
                break;
            }
        }
    }
}

Main.java

이제 Main은 진짜 깔끔하다. 상품 만들고, 리스트에 담고, CommerceSystem 넘겨주고 끝!

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        // 상품 목록 설정
        Product galaxy  = new Product("Galaxy S25",  1200000, "최신 안드로이드 스마트폰",  0);
        Product iphone  = new Product("iPhone 16",   1350000, "Apple의 최신 스마트폰",    10);
        Product macbook = new Product("MacBook Pro", 2400000, "M3 칩셋이 탑재된 노트북",  20);
        Product airpods = new Product("AirPods Pro",  350000, "노이즈 캔슬링 무선 이어폰", 100);

        List<Product> productList = new ArrayList<>();
        productList.add(galaxy);
        productList.add(iphone);
        productList.add(macbook);
        productList.add(airpods);

        CommerceSystem commerceSystem = new CommerceSystem(productList, scanner);

        // 프로그램 시작
        commerceSystem.start();
    }
}

배운 점 & 깨달음

1. 객체 지향 설계

STEP1에서는 Main이 모든 걸 다 했다.
STEP2에서는 각 클래스가 자기 역할만 담당한다.

 

코드가 길어질수록 이렇게 역할을 나눠야 유지보수가 편해진다고 한다.

2. 생성자 주입 

CommerceSystem commerceSystem = new CommerceSystem(productList, scanner);

CommerceSystem이 직접 productList를 만드는 게 아니라,
Main에서 만들어서 생성자로 넣어준다.
이렇게 하면 CommerceSystem은 어떤 리스트든 받아서 동작할 수 있다.

3. this 키워드

public CommerceSystem(List<Product> productList, Scanner scanner) {
    this.productList = productList;
    this.scanner = scanner;
}

받아오는 변수 이름이랑 필드 변수 이름이 똑같을 때 this로 구분해준다.


느낀 점

STEP1에서는 클래스를 배웠다면
STEP2에서는 클래스를 왜 나누는지 배웠다.

 

아직 완벽하게 이해한 것 같지는 않지만 클래스 흐름이 이해가기 시작했다.

 

Main이 점점 가벼워지는 게 눈에 보이니까 객체 지향이 왜 좋은지 조금 알 것 같다.
처음엔 왜 굳이 CommerceSystem을 따로 만드나 싶었는데,
직접 분리해보니까 확실히 코드가 읽기 편해졌다.


내일 계획

  • STEP2 복습
  • STEP3 도전
  • this 키워드 + 생성자 주입 패턴 복습