๐๏ธ Java ๋ฐฑ์๋ ๊ฐ๋ฐ์๋ฅผ ์ํ ํด๋์ค ์์ ์ ๋ณต !!
๐ค ํด๋์ค๋ ๋ฌด์์ธ๊ฐ?
ํด๋์ค(Class)๋ ๊ฐ์ฒด(Object)๋ฅผ ๋ง๋ค์ด๋ด๊ธฐ ์ํ โ์ค๊ณ๋โ ๋๋ โํโ์ ๋๋ค.
๐ฅฎ ๋ถ์ด๋นต์ผ๋ก ์ดํดํ๋ ํด๋์ค
- ๋ถ์ด๋นต ํ = ํด๋์ค (์ค๊ณ๋)
- ์ค์ ๋ถ์ด๋นต = ๊ฐ์ฒด (์ธ์คํด์ค)
- ํฅ, ์ํฌ๋ฆผ ๋ฑ = ํ๋ (์์ฑ)
- ๊ตฝ๊ธฐ, ํฌ์ฅํ๊ธฐ ๋ฑ = ๋ฉ์๋ (ํ์)
// ๐ช Product ํด๋์ค (์ํ ์ค๊ณ๋)
public class Product {
// ๋ถ์ด๋นต์ '๋ง'์ฒ๋ผ ๊ฐ ์ํ์ด ๊ฐ์ง๋ ๊ณ ์ ํ ์์ฑ๋ค
private String name; // ์ํ๋ช
private int price; // ๊ฐ๊ฒฉ
private int stockQuantity; // ์ฌ๊ณ ์๋
}
// ์ค์ ์ํ ๊ฐ์ฒด๋ค ์์ฑ
Product apple = new Product(); // ๐ ์ฌ๊ณผ ๊ฐ์ฒด
Product banana = new Product(); // ๐ ๋ฐ๋๋ ๊ฐ์ฒด
๐งฉ ํด๋์ค์ ๊ตฌ์ฑ์์
ํด๋์ค๋ ํฌ๊ฒ ๋ ๊ฐ์ง ํต์ฌ ์์๋ก ์ด๋ฃจ์ด์ ธ ์์ต๋๋ค.
1. ๐ฆ ํ๋ (Fields) - ์์ฑ๊ณผ ์ํ
๊ฐ์ฒด๊ฐ ๊ฐ์ง ๋ฐ์ดํฐ๋ฅผ ์ ์ํ๋ ๋ถ๋ถ์ ๋๋ค.
public class Product {
// โ
ํ๋๋ค - "์ด ๊ฐ์ฒด๋ ์ด๋ค ์ ๋ณด๋ฅผ ๊ฐ์ง๊ณ ์๋๊ฐ?"
private String name; // ์ํ๋ช
private int price; // ๊ฐ๊ฒฉ
private int stockQuantity; // ์ฌ๊ณ ์๋
private String category; // ์นดํ
๊ณ ๋ฆฌ
private boolean isActive; // ํ๋งค์ค ์ฌ๋ถ
}
ํน์ง:
- ๊ฐ์ฒด์ ์ํ(State)๋ฅผ ๋ํ๋ ๋๋ค
- ๊ฐ ๊ฐ์ฒด๋ง๋ค ๊ณ ์ ํ ๊ฐ์ ๊ฐ์ง๋๋ค
- ๋ฐ์ดํฐ ํ์ ์ ๋ช ์ํด์ผ ํฉ๋๋ค
2. โ๏ธ ๋ฉ์๋ (Methods) - ํ์์ ๊ธฐ๋ฅ
๊ฐ์ฒด๊ฐ ์ํํ ์ ์๋ ๋์์ ์ ์ํ๋ ๋ถ๋ถ์ ๋๋ค.
public class Product {
private String name;
private int price;
private int stockQuantity;
// โ
๋ฉ์๋๋ค - "์ด ๊ฐ์ฒด๋ ๋ฌด์์ ํ ์ ์๋๊ฐ?"
// ์ฌ๊ณ ๊ฐ์
public void decreaseStock(int quantity) {
if (quantity <= 0) {
throw new IllegalArgumentException("์๋์ ์์์ฌ์ผ ํฉ๋๋ค");
}
if (this.stockQuantity < quantity) {
throw new IllegalStateException("์ฌ๊ณ ๊ฐ ๋ถ์กฑํฉ๋๋ค");
}
this.stockQuantity -= quantity;
}
// ๊ฐ๊ฒฉ ๋ณ๊ฒฝ
public void changePrice(int newPrice) {
if (newPrice <= 0) {
throw new IllegalArgumentException("๊ฐ๊ฒฉ์ 0๋ณด๋ค ์ปค์ผ ํฉ๋๋ค");
}
this.price = newPrice;
}
// ์ฌ๊ณ ํ์ธ
public boolean hasStock() {
return this.stockQuantity > 0;
}
// ์ํ ์ ๋ณด ์กฐํ
public String getProductInfo() {
return String.format("์ํ๋ช
: %s, ๊ฐ๊ฒฉ: %d์, ์ฌ๊ณ : %d๊ฐ",
name, price, stockQuantity);
}
}
ํน์ง:
- ๊ฐ์ฒด์ ํ๋(Behavior)์ ๋ํ๋ ๋๋ค
- ํ๋ ๊ฐ์ ์ด์ฉํด ๋น์ฆ๋์ค ๋ก์ง์ ์ํํฉ๋๋ค
- ๋งค๊ฐ๋ณ์์ ๋ฐํ๊ฐ์ ๊ฐ์ง ์ ์์ต๋๋ค
๐ฏ ์ธ์ ํด๋์ค๋ฅผ ์ฌ์ฉํ ๊น?
โ ์ ํฉํ ์ํฉ
-
๋์ผํ ๊ตฌ์กฐ์ ๊ฐ์ฒด๊ฐ ์ฌ๋ฌ ๊ฐ ํ์ํ ๊ฒฝ์ฐ
// ๐ ์ผํ๋ชฐ์์ ์๋ง์ ์ํ๋ค์ ๊ด๋ฆฌํด์ผ ํ ๋ Product laptop = new Product("๋ ธํธ๋ถ", 1500000, 10); Product mouse = new Product("๋ง์ฐ์ค", 25000, 50); Product keyboard = new Product("ํค๋ณด๋", 80000, 30);
-
ํ์ค ์ธ๊ณ์ ๊ฐ๋
์ ์ฝ๋๋ก ํํํด์ผ ํ๋ ๊ฒฝ์ฐ
// ๐ช ์ ์์๊ฑฐ๋ ๋๋ฉ์ธ ๋ชจ๋ธ๋ง public class Customer { /* ๊ณ ๊ฐ */ } public class Order { /* ์ฃผ๋ฌธ */ } public class Payment { /* ๊ฒฐ์ */ } public class Delivery { /* ๋ฐฐ์ก */ }
-
๊ด๋ จ๋ ๋ฐ์ดํฐ์ ๊ธฐ๋ฅ์ ๋ฌถ์ด์ ๊ด๋ฆฌํด์ผ ํ๋ ๊ฒฝ์ฐ
// ๐ ๊ณ์ฐ๊ธฐ ๊ธฐ๋ฅ์ ํ๋์ ํด๋์ค๋ก ๋ฌถ๊ธฐ public class Calculator { private double result; // ๊ณ์ฐ ๊ฒฐ๊ณผ ์ ์ฅ public void add(double value) { /* ๋ํ๊ธฐ */ } public void subtract(double value) { /* ๋นผ๊ธฐ */ } public double getResult() { /* ๊ฒฐ๊ณผ ์กฐํ */ } }
๐ ์ ํด๋์ค๋ฅผ ์ฌ์ฉํ ๊น?
1. ๐ ์ฝ๋์ ์ฌ์ฌ์ฉ์ฑ (Reusability)
// โ ํด๋์ค ์์ด ๊ฐ๋ฐํ๋ฉด...
String product1Name = "๋
ธํธ๋ถ";
int product1Price = 1500000;
int product1Stock = 10;
String product2Name = "๋ง์ฐ์ค";
int product2Price = 25000;
int product2Stock = 50;
// ๋งค๋ฒ ๋ณ์๋ฅผ ๋ฐ๋ณตํด์ ์ ์ธํด์ผ ํจ ๐ต
// โ
ํด๋์ค๋ฅผ ์ฌ์ฉํ๋ฉด!
Product product1 = new Product("๋
ธํธ๋ถ", 1500000, 10);
Product product2 = new Product("๋ง์ฐ์ค", 25000, 50);
// ๊น๋ํ๊ณ ์ผ๊ด๋ ๊ตฌ์กฐ! ๐
2. ๐ ์ฒด๊ณ์ ์ธ ์ฝ๋ ๊ด๋ฆฌ (Organization)
// โ
Product ๊ด๋ จ ๋ชจ๋ ๊ฒ์ด ํ ๊ณณ์!
public class Product {
// ์ํ ๋ฐ์ดํฐ
private String name;
private int price;
// ์ํ ๊ธฐ๋ฅ
public void validatePrice() { /* ๊ฐ๊ฒฉ ๊ฒ์ฆ */ }
public void applyDiscount() { /* ํ ์ธ ์ ์ฉ */ }
public void updateStock() { /* ์ฌ๊ณ ์
๋ฐ์ดํธ */ }
}
3. ๐ ํ์ค ์ธ๊ณ ๋ชจ๋ธ๋ง (Domain Modeling)
// ๐ฆ ์ํ ์์คํ
์์
public class Account {
private String accountNumber; // ๊ณ์ข๋ฒํธ
private long balance; // ์์ก
public void deposit(long amount) { // ์
๊ธ
this.balance += amount;
}
public void withdraw(long amount) { // ์ถ๊ธ
if (balance >= amount) {
this.balance -= amount;
}
}
}
4. ๐ ๋ฐ์ดํฐ ๋ณดํธ (์บก์ํ, Encapsulation)
public class BankAccount {
private long balance; // โ
private์ผ๋ก ์ง์ ์ ๊ทผ ์ฐจ๋จ
// โ
์์ ํ ๋ฐฉ๋ฒ์ผ๋ก๋ง ์์ก ๋ณ๊ฒฝ ๊ฐ๋ฅ
public void deposit(long amount) {
if (amount <= 0) {
throw new IllegalArgumentException("์
๊ธ์ก์ ์์์ฌ์ผ ํฉ๋๋ค");
}
this.balance += amount;
}
// โ ์ธ๋ถ์์ balance์ ์ง์ ์ ๊ทผ ๋ถ๊ฐ
// account.balance = -1000000; // ์ปดํ์ผ ์๋ฌ!
}
๐ ๏ธ ์ค์ ํด๋์ค ์์ฑ ๊ฐ์ด๋
๐ ํด๋์ค ์ค๊ณ ์ฒดํฌ๋ฆฌ์คํธ
// โ
์ข์ ํด๋์ค ์์
public class Product {
// 1. ํ๋๋ private์ผ๋ก ๋ณดํธ
private ProductId id;
private String name;
private Money price;
private Stock stock;
// 2. ์์ฑ์๋ก ํ์ ๋ฐ์ดํฐ ๋ณด์ฅ
public Product(ProductId id, String name, Money price) {
this.id = Objects.requireNonNull(id);
this.name = validateName(name);
this.price = Objects.requireNonNull(price);
this.stock = Stock.zero();
}
// 3. ๋น์ฆ๋์ค ๋ก์ง์ ๋ฉ์๋๋ก ํํ
public void changePrice(Money newPrice) {
if (newPrice.isLessThanOrEqual(Money.zero())) {
throw new IllegalArgumentException("์ํ ๊ฐ๊ฒฉ์ 0๋ณด๋ค ์ปค์ผ ํฉ๋๋ค");
}
this.price = newPrice;
}
// 4. ์๋ฏธ์๋ ๋ฉ์๋๋ช
์ฌ์ฉ
public boolean isAvailable() {
return stock.hasQuantity();
}
// 5. ํ์ํ ๊ฒฝ์ฐ์๋ง getter ์ ๊ณต
public String getName() {
return name;
}
}
โ ๏ธ ํผํด์ผ ํ ์ํฐํจํด
// โ ๋์ ํด๋์ค ์์
public class Product {
// 1. ๋ชจ๋ ํ๋๊ฐ public (์บก์ํ ์๋ฐ)
public String name;
public int price;
public int stock;
// 2. ์๋ฏธ์๋ getter/setter๋ง ์กด์ฌ (๋น์ฝํ ๋๋ฉ์ธ ๋ชจ๋ธ)
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public int getPrice() { return price; }
public void setPrice(int price) { this.price = price; }
// 3. ๋น์ฆ๋์ค ๋ก์ง์ด ์์
// ์ค์ ์ํ์ ํ๋์ด๋ ๊ท์น์ด ํํ๋์ง ์์
}
๐ฏ ๋ฐฑ์๋ ๊ฐ๋ฐ์์์ ํด๋์ค ํ์ฉ
๐ช ์ ์์๊ฑฐ๋ ๋๋ฉ์ธ ์์
// ๐ฆ ์ฃผ๋ฌธ ์ ๊ทธ๋ฆฌ๊ฒ์ดํธ
public class Order {
private OrderId id;
private CustomerId customerId;
private List<OrderItem> items = new ArrayList<>();
private OrderStatus status;
private LocalDateTime orderedAt;
public void addItem(Product product, int quantity) {
validateCanAddItem();
OrderItem item = new OrderItem(product, quantity);
items.add(item);
}
public void confirm() {
if (status != OrderStatus.PENDING) {
throw new IllegalStateException("๋๊ธฐ ์ค์ธ ์ฃผ๋ฌธ๋ง ํ์ ํ ์ ์์ต๋๋ค");
}
this.status = OrderStatus.CONFIRMED;
}
}
// ๐ฐ ๊ฒฐ์ ์๋น์ค
@Service
public class PaymentService {
public PaymentResult processPayment(Order order, PaymentMethod method) {
validateOrder(order);
Money totalAmount = order.calculateTotal();
Payment payment = Payment.create(order.getId(), totalAmount, method);
return paymentGateway.process(payment);
}
}
๐ ํต์ฌ ์ฉ์ด ์ ๋ฆฌ
์ฉ์ด | ์์ด | ์ค๋ช | ์์ |
---|---|---|---|
ํด๋์ค | Class | ๊ฐ์ฒด๋ฅผ ๋ง๋ค๊ธฐ ์ํ ์ค๊ณ๋ | public class Product { } |
๊ฐ์ฒด | Object | ํด๋์ค๋ก๋ถํฐ ์์ฑ๋ ์ค์ฒด | Product apple = new Product(); |
์ธ์คํด์ค | Instance | ๋ฉ๋ชจ๋ฆฌ์ ํ ๋น๋ ๊ฐ์ฒด | apple์ Product์ ์ธ์คํด์ค |
ํ๋ | Field | ๊ฐ์ฒด์ ์ํ๋ฅผ ๋ํ๋ด๋ ๋ณ์ | private String name; |
๋ฉ์๋ | Method | ๊ฐ์ฒด์ ํ๋์ ๋ํ๋ด๋ ํจ์ | public void changePrice() { } |
์์ฑ์ | Constructor | ๊ฐ์ฒด๋ฅผ ์ด๊ธฐํํ๋ ํน๋ณํ ๋ฉ์๋ | public Product(String name) { } |
์บก์ํ | Encapsulation | ๋ฐ์ดํฐ์ ๋ฉ์๋๋ฅผ ํ๋๋ก ๋ฌถ๊ณ ๋ณดํธ |
private ์ ๊ทผ ์ ์ด์ ์ฌ์ฉ |
๐ ๋ง๋ฌด๋ฆฌ
ํด๋์ค๋ Java ๋ฐฑ์๋ ๊ฐ๋ฐ์ ํต์ฌ ๊ธฐ์ด์ ๋๋ค!
๐ฆ ๋ค์ ๋จ๊ณ ํ์ต ๋ก๋๋งต
- ์์ (Inheritance) - ํด๋์ค ๊ฐ์ ๊ด๊ณ ์ดํด
- ๋คํ์ฑ (Polymorphism) - ๊ฐ์ ๋ฉ์๋, ๋ค๋ฅธ ๋์
- ์ถ์ํ (Abstraction) - ์ธํฐํ์ด์ค์ ์ถ์ ํด๋์ค
- ์ปฌ๋ ์ (Collections) - ๊ฐ์ฒด๋ค์ ํจ์จ์ ์ผ๋ก ๊ด๋ฆฌ
- ๋์์ธ ํจํด - ๊ฒ์ฆ๋ ์ค๊ณ ํด๋ฒ๋ค
๐ก ์ค์ต ์ถ์ฒ
- ๊ฐ๋จํ ์ผํ๋ชฐ ์ํ ๊ด๋ฆฌ ์์คํ ๋ง๋ค๊ธฐ
- ์ํ ๊ณ์ข ํด๋์ค๋ก ์ ์ถ๊ธ ๊ธฐ๋ฅ ๊ตฌํํ๊ธฐ
- ํ์ ์ฑ์ ๊ด๋ฆฌ ์์คํ ์ค๊ณํด๋ณด๊ธฐ
ํด๋์ค๋ฅผ ์ ๋ณตํ๋ฉด ๊ฐ์ฒด์งํฅ ํ๋ก๊ทธ๋๋ฐ์ ๋ฌธ์ด ํ์ง ์ด๋ฆฝ๋๋ค! ๐