์ด์ง€๋ฏผ์˜ ๊ฐœ๋ฐœ ๋…ธํŠธ

๋ฐฑ์—”๋“œ ๊ฐœ๋ฐœ์„ ๊ณต๋ถ€ํ•˜๋ฉฐ Java์™€ Spring์„ ์ค‘์‹ฌ์œผ๋กœ ํ•™์Šต ๊ธฐ๋ก์„ ์ •๋ฆฌํ•˜๋Š” ๊ณต๊ฐ„์ž…๋‹ˆ๋‹ค.

๐Ÿ”ฅ ๋‚ด์ผ๋ฐฐ์›€์บ ํ”„/๐Ÿ“Œ ๊ณผ์ œ

[๋‚ด์ผ๋ฐฐ์›€์บ ํ”„ Spring_3๊ธฐ] CH2 ์ปค๋จธ์Šค ๊ณผ์ œ - ๋„์ „๊ธฐ๋Šฅ

jiiimni 2026. 1. 28. 11:55

ํ•„์ˆ˜ ๊ธฐ๋Šฅ ๊ตฌํ˜„ ์ดํ›„ Enum, ๋žŒ๋‹ค, ์ŠคํŠธ๋ฆผ์„ ์‹ค์ œ๋กœ ์ ์šฉํ•ด๋ณด์•˜๋‹ค.

  • ์žฅ๋ฐ”๊ตฌ๋‹ˆ์™€ ์ฃผ๋ฌธ ํ๋ฆ„์„ ์‹ค์ œ ์„œ๋น„์Šค์ฒ˜๋Ÿผ ์„ค๊ณ„ํ•˜๊ธฐ
  • ๊ด€๋ฆฌ์ž ๋ชจ๋“œ๋ฅผ ํ†ตํ•œ ์ƒํ’ˆ ๊ด€๋ฆฌ ๊ธฐ๋Šฅ ์ถ”๊ฐ€
  • Enum์„ ํ™œ์šฉํ•œ ๊ณ ๊ฐ ๋“ฑ๊ธ‰ ๊ด€๋ฆฌ
  • ๋žŒ๋‹ค์™€ ์ŠคํŠธ๋ฆผ์„ ํ™œ์šฉํ•œ ๋ฐ์ดํ„ฐ ์กฐํšŒ ๋ฐ ๊ด€๋ฆฌ

์ƒ๊ฐํ•ด๋ณด๊ธฐ

CommerceSystem์— ๋ชจ๋“  ๋กœ์ง์ด ๋ชฐ๋ฆฌ์ง€ ์•Š๋„๋ก ํ•˜๋Š” ๊ฒŒ ๋ชฉํ‘œ์˜€๋‹ค.

์žฅ๋ฐ”๊ตฌ๋‹ˆ ๊ด€๋ จ ๋กœ์ง์€ Cart๊ฐ€ ์ฑ…์ž„์ง€๋„๋ก ๋ถ„๋ฆฌํ•˜๊ณ 
์ƒํ’ˆ ๊ด€๋ฆฌ ๋กœ์ง์€ Category์™€ Product๊ฐ€ ๋‹ด๋‹นํ•˜๋„๋ก ํ–ˆ๋‹ค.


Product ํด๋ž˜์Šค

์ƒํ’ˆ์˜ ๊ธฐ๋ณธ ์ •๋ณด๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ๊ฐ์ฒด์ด๋‹ค.
์ƒํ’ˆ๋ช…, ๊ฐ€๊ฒฉ, ์„ค๋ช…, ์žฌ๊ณ  ์ˆ˜๋Ÿ‰์„ ํ•„๋“œ๋กœ ๊ฐ€์ง€๊ณ 
์žฌ๊ณ  ์ฐจ๊ฐ์€ decreaseStock() ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด์„œ๋งŒ ๊ฐ€๋Šฅํ•˜๋„๋ก ์ œํ•œํ–ˆ๋‹ค.

public void decreaseStock(int quantity) {
    if (stock < quantity) {
        throw new IllegalArgumentException("์žฌ๊ณ ๊ฐ€ ๋ถ€์กฑํ•ฉ๋‹ˆ๋‹ค.");
    }
    stock -= quantity;
}

์žฌ๊ณ  ๋ณ€๊ฒฝ ๋กœ์ง์„ ํ•œ ๊ณณ์— ๋ชจ์•„ ์ž˜๋ชป๋œ ์ƒํƒœ ๋ณ€๊ฒฝ์„ ๋ฐฉ์ง€ํ•˜๋ ค๊ณ  ํ–ˆ๋‹ค.

Product.java ์ „์ฒด ์ฝ”๋“œ

package kr.spartaclub.com.example.commerce;

public class Product {
    private final String name;
    private int price;
    private String description;
    private int stock;

    public Product(String name, int price, String description, int stock) {
        this.name = name;
        this.price = price;
        this.description = description;
        this.stock = stock;
    }

    public String getName() {
        return name;
    }

    public int getPrice() {
        return price;
    }

    public String getDescription() {
        return description;
    }

    public int getStock() {
        return stock;
    }

    // ์ฃผ๋ฌธ ํ™•์ • ์‹œ ์žฌ๊ณ  ๊ฐ์†Œ๋ฅผ ์œ„ํ•œ ๋ฉ”์„œ๋“œ
    public void decreaseStock(int quantity) {
        if (quantity <= 0) {
            throw new IllegalArgumentException("์ฐจ๊ฐ ์ˆ˜๋Ÿ‰์€ 0๋ณด๋‹ค ์ปค์•ผ ํ•ฉ๋‹ˆ๋‹ค.");
        }
        if (stock < quantity) {
            throw new IllegalArgumentException("์žฌ๊ณ ๊ฐ€ ๋ถ€์กฑํ•ฉ๋‹ˆ๋‹ค.");
        }
        stock -= quantity;
    }

    public void setPrice(int price) {
        if (price <= 0) throw new IllegalArgumentException("๊ฐ€๊ฒฉ์€ 0์›๋ณด๋‹ค ์ปค์•ผ ํ•ฉ๋‹ˆ๋‹ค.");
        this.price = price;
    }

    public void setDescription(String description) {
        if (description == null || description.isBlank())
            throw new IllegalArgumentException("์„ค๋ช…์€ ๋น„์–ด ์žˆ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.");
        this.description = description;
    }

    public void setStock(int stock) {
        if (stock < 0) throw new IllegalArgumentException("์žฌ๊ณ ๋Š” 0๊ฐœ ์ด์ƒ์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.");
        this.stock = stock;
    }
}

Category ํด๋ž˜์Šค

์นดํ…Œ๊ณ ๋ฆฌ๋ณ„๋กœ ์ƒํ’ˆ์„ ๊ด€๋ฆฌํ•˜๋Š” ์—ญํ• ์„ ๋‹ด๋‹นํ•œ๋‹ค.
์นดํ…Œ๊ณ ๋ฆฌ ์ด๋ฆ„๊ณผ ์ƒํ’ˆ ๋ฆฌ์ŠคํŠธ๋ฅผ ๋ณด์œ ํ•˜๊ณ 
์นดํ…Œ๊ณ ๋ฆฌ ๋‹จ์œ„๋กœ ์ƒํ’ˆ ์กฐํšŒ ๋ฐ ๊ด€๋ฆฌ ๊ธฐ๋Šฅ์ด ์žˆ๋‹ค.

์นดํ…Œ๊ณ ๋ฆฌ๋ฅผ ๋„์ž…ํ•˜๋ฉด์„œ ์ƒํ’ˆ ์กฐํšŒ ๋กœ์ง์„ ๋” ๋ช…ํ™•ํ•˜๊ฒŒ ๋ถ„๋ฆฌํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.

Category.java ์ „์ฒด ์ฝ”๋“œ

package kr.spartaclub.com.example.commerce.challenge;

import kr.spartaclub.com.example.commerce.Product;

import java.util.List;

public class Category {

    private final String name;
    private final List<Product> products;

    public Category(String name, List<Product> products) {
        this.name = name;
        this.products = products;
    }

    public String getName() {
        return name;
    }

    public List<Product> getProducts() {
        return products;
    }
}

Cart / CartItem ํด๋ž˜์Šค

์žฅ๋ฐ”๊ตฌ๋‹ˆ ๊ธฐ๋Šฅ์„ ๋‹ด๋‹นํ•˜๋Š” ํ•ต์‹ฌ ๊ฐ์ฒด์ด๋‹ค.

  • Cart๋Š” ์žฅ๋ฐ”๊ตฌ๋‹ˆ ์ „์ฒด๋ฅผ ๊ด€๋ฆฌ
  • CartItem์€ ์ƒํ’ˆ + ์ˆ˜๋Ÿ‰ ํ•œ ์ค„์˜ ์˜๋ฏธ
public void add(Product product, int quantity) {
    for (CartItem item : items) {
        if (item.getProduct() == product) {
            item.addQuantity(quantity);
            return;
        }
    }
    items.add(new CartItem(product, quantity));
}

์ด๋ฏธ ๋‹ด๊ธด ์ƒํ’ˆ์ผ ๊ฒฝ์šฐ ์ˆ˜๋Ÿ‰๋งŒ ์ฆ๊ฐ€์‹œํ‚ค๋„๋ก ๊ตฌํ˜„ํ•ด
์žฅ๋ฐ”๊ตฌ๋‹ˆ ๊ตฌ์กฐ๋ฅผ ๋‹จ์ˆœํ•˜๊ฒŒ ์œ ์ง€ํ–ˆ๋‹ค.

Cart.java ์ „์ฒด ์ฝ”๋“œ

package kr.spartaclub.com.example.commerce.challenge;

import kr.spartaclub.com.example.commerce.Product;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class Cart {

    private List<CartItem> items = new ArrayList<>();

    public boolean isEmpty() {
        return items.isEmpty();
    }

    public List<CartItem> getItems() {
        return Collections.unmodifiableList(items);
    }

    public void add(Product product, int quantity) {
        if (quantity <= 0) throw new IllegalArgumentException("์ˆ˜๋Ÿ‰์€ 1๊ฐœ ์ด์ƒ์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.");

        for (CartItem item : items) {
            if (item.getProduct() == product) {
                item.addQuantity(quantity);
                return;
            }
        }
        items.add(new CartItem(product, quantity));
    }

    public int getTotalAmount() {
        int sum = 0;
        for (CartItem item : items) {
            sum += item.getTotalPrice();
        }
        return sum;
    }

    public void clear() {
        items.clear();
    }

    public void removeProduct(Product product) {
        items.removeIf(item -> item.getProduct() == product);
    }

    public boolean removeByProductName(String name) {
        int before = items.size();
        items = items.stream()
                .filter(item -> !item.getProduct().getName().equalsIgnoreCase(name.trim()))
                .toList();
        items = new ArrayList<>(items);
        return items.size() != before;
    }
}

CartItem.java ์ „์ฒด ์ฝ”๋“œ

package kr.spartaclub.com.example.commerce.challenge;

import kr.spartaclub.com.example.commerce.Product;

public class CartItem {
    private final Product product;
    private int quantity;

    public CartItem(Product product, int quantity) {
        if (product == null) throw new IllegalArgumentException("์ƒํ’ˆ์ด null์ผ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.");
        if (quantity <= 0) throw new IllegalArgumentException("์ˆ˜๋Ÿ‰์€ 1๊ฐœ ์ด์ƒ์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.");

        this.product = product;
        this.quantity = quantity;
    }

    public Product getProduct() {
        return product;
    }

    public int getQuantity() {
        return quantity;
    }

    public void addQuantity(int add) {
        if (add <= 0) throw new IllegalArgumentException("์ถ”๊ฐ€ ์ˆ˜๋Ÿ‰์€ 1๊ฐœ ์ด์ƒ์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.");
        this.quantity += add;
    }

    public int getTotalPrice() {
        return product.getPrice() * quantity;
    }
}

CommerceSystem ํด๋ž˜์Šค

ํ”„๋กœ๊ทธ๋žจ ์ „์ฒด ํ๋ฆ„์„ ์ œ์–ดํ•˜๋Š” ํด๋ž˜์Šค์ด๋‹ค.
๋ฉ”์ธ ๋ฉ”๋‰ด ์ถœ๋ ฅ, ์‚ฌ์šฉ์ž ์ž…๋ ฅ ์ฒ˜๋ฆฌ, ์นดํ…Œ๊ณ ๋ฆฌ ์ด๋™, ์ฃผ๋ฌธ ํ๋ฆ„ ์ œ์–ด, ๊ด€๋ฆฌ์ž ๋ชจ๋“œ ์ง„์ž… ๋“ฑ
์‹ค์ œ ๋กœ์ง์€ ๊ฐ ๊ฐ์ฒด์— ์œ„์ž„ํ•˜๊ณ , CommerceSystem์€ ํ๋ฆ„ ์ œ์–ด์ž ์—ญํ• ์— ์ง‘์ค‘ํ•˜๋„๋ก ์„ค๊ณ„ํ–ˆ๋‹ค.

์ „์ฒด ์ฝ”๋“œ๋Š” ๋„ˆ๋ฌด ๊ธธ์–ด์„œ GitHub๋ฅผ ํ†ตํ•ด ํ™•์ธํ–ˆ๋‹ค.

@jiiim_ni CommerceProject - github ๋งํฌ

ํ…Œ์ŠคํŠธ๋ฅผ ์œ„ํ•ด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ณ ๊ฐ ๋ฐ์ดํ„ฐ๋ฅผ ์ƒ์„ฑํ–ˆ๋‹ค.

customers.put("bronze@test.com", new Customer("๋ธŒ๋ก ์ฆˆ", "bronze@test.com", CustomerGrade.BRONZE, 0));
customers.put("silver@test.com", new Customer("์‹ค๋ฒ„", "silver@test.com", CustomerGrade.SILVER, 600_000));
customers.put("gold@test.com", new Customer("๊ณจ๋“œ", "gold@test.com", CustomerGrade.GOLD, 1_200_000));
customers.put("platinum@test.com", new Customer("ํ”Œ๋ž˜ํ‹ฐ๋„˜", "platinum@test.com", CustomerGrade.PLATINUM, 2_500_000));

ํ•ต์‹ฌ ๋กœ์ง

Lv1. ์žฅ๋ฐ”๊ตฌ๋‹ˆ + ์ฃผ๋ฌธ ํ๋ฆ„

  • ์ƒํ’ˆ ์„ ํƒ → ์ˆ˜๋Ÿ‰ ์ž…๋ ฅ → ์žฅ๋ฐ”๊ตฌ๋‹ˆ ๋‹ด๊ธฐ
  • ์žฅ๋ฐ”๊ตฌ๋‹ˆ ์กฐํšŒ ์‹œ ์ด ๊ธˆ์•ก ๊ณ„์‚ฐ
  • ์ฃผ๋ฌธ ํ™•์ • ์‹œ ์žฌ๊ณ  ์ฐจ๊ฐ
  • ์ฃผ๋ฌธ ์ทจ์†Œ ์‹œ ์žฅ๋ฐ”๊ตฌ๋‹ˆ ์ดˆ๊ธฐํ™”

๊ฐ€์žฅ ์ค‘์š”ํ•˜๊ฒŒ ๊ณ ๋ คํ•œ ์ ์€ ์žฌ๊ณ  ์ฐจ๊ฐ ์‹œ์ ์ด์—ˆ๋‹ค.
์žฅ๋ฐ”๊ตฌ๋‹ˆ์— ๋‹ด๋Š” ์ˆœ๊ฐ„์ด ์•„๋‹ˆ๋ผ ์ฃผ๋ฌธ ํ™•์ • ์‹œ์ ์—๋งŒ ์žฌ๊ณ ๋ฅผ ์ฐจ๊ฐํ•˜๋„๋ก ๊ตฌํ˜„ํ–ˆ๋‹ค.


Lv2. ๊ด€๋ฆฌ์ž ๋ชจ๋“œ

  • ๋น„๋ฐ€๋ฒˆํ˜ธ ์ธ์ฆ (3ํšŒ ์‹คํŒจ ์‹œ ๋ฉ”์ธ ๋ฉ”๋‰ด ๋ณต๊ท€)
  • ์ƒํ’ˆ ์ถ”๊ฐ€ / ์ˆ˜์ • / ์‚ญ์ œ
  • ์นดํ…Œ๊ณ ๋ฆฌ ์„ ํƒ ํ›„ ์ƒํ’ˆ ๊ด€๋ฆฌ
  • ์‚ญ์ œ๋œ ์ƒํ’ˆ์ด ์žฅ๋ฐ”๊ตฌ๋‹ˆ์— ์žˆ์„ ๊ฒฝ์šฐ ํ•จ๊ป˜ ์ œ๊ฑฐ

์ƒํ’ˆ ์ˆ˜์ • ์‹œ์—๋Š” ๊ฐ€๊ฒฉ, ์„ค๋ช…, ์žฌ๊ณ ๋ฅผ ๊ฐ๊ฐ ์„ ํƒ์ ์œผ๋กœ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๊ตฌํ˜„ํ–ˆ๋‹ค.


Lv3. Enum, ๋žŒ๋‹ค & ์ŠคํŠธ๋ฆผ ํ™œ์šฉ

๊ณ ๊ฐ ๋“ฑ๊ธ‰ ํ• ์ธ(Enum)์„ ์ •์˜ํ•ด ๋“ฑ๊ธ‰๋ณ„ ํ• ์ธ์œจ์„ ๊ด€๋ฆฌํ–ˆ๋‹ค.

public enum CustomerGrade {
    BRONZE(0),
    SILVER(5),
    GOLD(10),
    PLATINUM(15);
}

CustomerGrade.java ์ „์ฒด ์ฝ”๋“œ

package kr.spartaclub.com.example.commerce.challenge;

public enum CustomerGrade {
    BRONZE(0),
    SILVER(5),
    GOLD(10),
    PLATINUM(15);

    private final int discountPercent;

    CustomerGrade(int discountPercent) {
        this.discountPercent = discountPercent;
    }

    public int getDiscountPercent() {
        return discountPercent;
    }

    public double getDiscountRate() {
        return discountPercent / 100.0;
    }
}

์ŠคํŠธ๋ฆผ ํ™œ์šฉ

๊ฐ€๊ฒฉ๋Œ€๋ณ„ ์ƒํ’ˆ ํ•„ํ„ฐ๋ง

products.stream()
        .filter(p -> p.getPrice() <= 1_000_000)
        .forEach(...);

์žฅ๋ฐ”๊ตฌ๋‹ˆ ์ƒํ’ˆ ์ œ๊ฑฐ

items = items.stream()
        .filter(item -> !item.getProduct().getName().equalsIgnoreCase(name))
        .toList();

๊ฒฐ๊ณผ

์žฌ๊ณ  ๋ณ€๊ฒฝ + ์ฃผ๋ฌธ ์ทจ์†Œ

 

 

 


๊ด€๋ฆฌ์ž ๋ชจ๋“œ

 

 


์ „์ฒด ๊ธฐ๋Šฅ ๊ฒฐ๊ณผ

 

 

 

 

 

 


ํŠธ๋Ÿฌ๋ธ”์ŠˆํŒ… ๋ฐ ํšŒ๊ณ 

1) ๋„์ „ ๊ธฐ๋Šฅ ๊ตฌํ˜„ ๋‚œ์ด๋„
๋„์ „ ๊ธฐ๋Šฅ๋ถ€ํ„ฐ๋Š” ์‹ค์ œ ์„œ๋น„์Šค ํ๋ฆ„์„ ๊ณ ๋ คํ•ด์•ผ ํ•ด์„œ ๋‹จ์ˆœ ๊ธฐ๋Šฅ ์ถ”๊ฐ€๋กœ๋Š” ํ•ด๊ฒฐ์ด ์–ด๋ ค์› ๋‹ค.
๊ธฐ๋Šฅ ํ•˜๋‚˜๊ฐ€ ๋‹ค๋ฅธ ๊ธฐ๋Šฅ์— ์—ฐ์‡„์ ์œผ๋กœ ์˜ํ–ฅ์„ ์ค€๋‹ค๋Š” ์ ์„ ์ฒด๊ฐํ–ˆ๋‹ค.

2) CommerceSystem ์ฝ”๋“œ ๋น„๋Œ€ํ™”
๋กœ์ง์ด ๋ชฐ๋ฆฌ๋ฉด์„œ ์ˆ˜์ • ํฌ์ธํŠธ๋ฅผ ์ฐพ๊ธฐ ์–ด๋ ค์› ๋‹ค.
๋ฉ”๋‰ด ํ•˜๋‚˜ ์ˆ˜์ •ํ•ด๋„ ์—ฌ๋Ÿฌ ๋ฉ”์„œ๋“œ๋ฅผ ๋™์‹œ์— ๋ด์•ผ ํ–ˆ๋‹ค.

3) ์ปค๋ฐ‹ ๊ด€๋ฆฌ ์‹คํŒจ
๊ธฐ๋Šฅ ๋‹จ์œ„๋กœ ์ปค๋ฐ‹ํ•˜์ง€ ์•Š์•„ ๋‚˜์ค‘์— ์ •๋ฆฌํ•  ๋•Œ ๋งค์šฐ ํ—ท๊ฐˆ๋ ธ๋‹ค.
์ž‘์€ ๋‹จ์œ„, ์‹คํ–‰ ๊ฐ€๋Šฅํ•œ ์ƒํƒœ์—์„œ ์ปค๋ฐ‹ํ•˜๋Š” ์Šต๊ด€์˜ ์ค‘์š”์„ฑ์„ ๋А๊ผˆ๋‹ค.

4) AI ํ™œ์šฉ์— ๋Œ€ํ•œ ํšŒ๊ณ 
AI๋ฅผ ์ •๋‹ต ์ƒ์„ฑ๊ธฐ๊ฐ€ ์•„๋‹ˆ๋ผ ๋ฐฉํ–ฅ ํžŒํŠธ์šฉ์œผ๋กœ ํ™œ์šฉํ•˜๋ ค๊ณ  ๋…ธ๋ ฅํ–ˆ๋‹ค.
์ฝ”๋“œ๋ฅผ ๊ทธ๋Œ€๋กœ ์“ฐ๊ธฐ๋ณด๋‹ค๋Š” ์ดํ•ด ํ›„ ์ง์ ‘ ์ž‘์„ฑํ•˜๋Š” ๋ฐฉ์‹์„ ์œ ์ง€ํ–ˆ๋‹ค.


ํ”„๋กœ์ ํŠธ ํŒŒ์ผ ์„ค์ •