Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 18 additions & 18 deletions 1/1.md
Original file line number Diff line number Diff line change
@@ -1,40 +1,40 @@
# OOP란 무엇인가요?

>
> Object-oriented programming으로 객체 지향 프로그래밍이라 한다. 프로그램을 메소드, 필드를 가지는 수많은 객체라는 단위로 나누고 이들의 상호 작용으로 서술하는 방식이다.

# OOP의 주요 특징 4가지에는 무엇이 있나요?

1.
2.
3.
4.
1. 캡슐화: 변수와 함수를 하나의 단위로 묶는 것.
2. 정보 은닉: 프로그램의 세부 구현이 드러나지 않도록 내부 모듈로 감추는 것.
3. 상속: 자식 클래스가 부모 클래스의 특성과 기능을 물려받는 것.
4. 다형성: 하나의 변수 또는 함수가 상황에 따라 다른 의미로 해석될 수 있는 것.

# 객체지향의 SOLID 법칙의 5가지 원칙에는 무엇이 있나요?

1.
2.
3.
4.
5.
1. SRP 단일 책임 원칙: 클래스는 단 하나의 책임만 가져야 한다.
2. OCP 개방 폐쇄 원칙: 클래스는 확장에 열려있어야 하며, 수정엔 닫혀있어야 한다.
3. LSP 리스코프 치환 원칙: 서브 타입은 언제나 부모 타입으로 교체할 수 있어야 한다.
4. ISP 인터페이스 분리 원칙: 인터페이스를 각각 사용에 맞게 잘게 분리해야 한다.
5. DIP 의존 역전 원칙: Class를 참조하려면 그 대상의 상위 요소로 참조해야 한다.

# 객체지향의 Tell, Don’t Ask가 무엇인가요?

>
> `객체에게 데이터를 요구하지 말고, 객체에게 일을 시켜라` 란 뜻으로, 캡슐화가 잘 이루어진 설계를 하기 위해서 탄생한 원칙.

# DRY, KISS에 대해 설명해주세요.

- DRY
- KISS
- DRY: Don't Repeat Yourself: 같은 코드를 반복하지 말아야 한다.
- KISS: Keep It Simple, Stupid: 불필요한 코드를 쓰지 말고 가장 단순하게 작성하라.

# 객체지향 설계에서 응집도와 결합도가 무엇인지 설명하고, 각각 높은 경우와 낮은 경우의 차이를 간단히 예를 들어보세요.

- 응집도:
- 결합도:
- 응집도: 한 모듈 내의 구성 요소 간의 밀접한 정도로, 응집도가 높을 수록 한 모듈이 하나의 책임을 갖고 있게 됨.
- 결합도: 모듈간의 상호 의존 정도, 연관된 관계의 끈끈함을 의미. 결합도가 과하게 높으면 한 클래스를 변경하면 다른 클래스도 변경해야 할 수도 있음.

**예시:**
- 응집도가 낮고 결합도가 높은 경우 ->
- 응집도가 높고 결합도가 낮은 경우 ->
- 응집도가 낮고 결합도가 높은 경우 -> 여러 기능들이 하나의 모듈에서 구동됨.
- 응집도가 높고 결합도가 낮은 경우 -> 여러 기능들이 독립적으로 존재하며 필요한 부분만 연결되어 구동됨.

# 자신이 생각하는 좋은 객체지향 코드의 조건을 말해보세요.

>
> 좋은 객체지향 코드는 간결하고, 이해하기 쉬우며 수정하기 쉬워야 함. 따라서 모듈 내 불필요한 코드 및 같은 기능을 하는 코드 제거, 한 모듈은 하나의 책임만 가지도록 해야 하는 것입니다.
183 changes: 182 additions & 1 deletion 2/src/Stock.java
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

개선사항 :
SRP -> Stock이 UI와 로직을 다 가지고 있음
DIP -> Stock이 구체 클래스에 직접 의존
개선법 :
SRP ->

  1. UI 담당 (StockUI)
  • 메뉴 출력, 입력만 담당.
  1. 애플리케이션 흐름 담당 (StockApp)
  • UI에서 입력받은 값을 해석하고, Store와 Validator를 호출하는 역할.
  1. 검증/저장은 기존대로 유지.
    DIP ->
    Store 인터페이스를 두고, Stock은 이 인터페이스에만 의존하게 하기.
    예시 :
interface ItemStore {
    void saveItem(Item item);
    Item[] getItems();
    int getSize();
}

인터페이스를 많이많이 사용합시다.

Original file line number Diff line number Diff line change
@@ -1,5 +1,186 @@
import java.util.InputMismatchException;
import java.util.Scanner;

public class Stock {
public static void main(String[] args) {
System.out.println("Stock Management System");
Scanner scanner = new Scanner(System.in);
Store store = new Store();
Items items = new Items(store);
StockController stock = new StockController(items, scanner);
stock.main();
scanner.close();
}
}

class StockController {
private final Items itemStore;
private final Scanner scanner;

public StockController(Items itemStore, Scanner scanner) {
this.itemStore = itemStore;
this.scanner = scanner;
}

public void main() {
while (true){
printMenu();
String inp = scanner.nextLine();
switch (inp){
case "1": handleSave(); break;
case "2": handleView(); break;
case "3": System.out.println("프로그램을 종료합니다."); return;
default: System.out.println("잘못된 입력입니다."); break;
}
}
}

private void printMenu() {
System.out.println("어떤기능을 이용하실건가요?");
System.out.println("1. 물품 신청");
System.out.println("2. 물품 조회");
System.out.println("3. 종료");
}

private void handleSave() {
if (itemStore.isFull()) {
System.out.println("물품 신청은 최대 5개까지 가능합니다.");
return;
}

System.out.println("어떤 물품을 신청하시겠습니까?");
System.out.print("신청자: ");
String name = scanner.nextLine();

System.out.print("물품명: ");
String item = scanner.nextLine();

Integer quantity = input(scanner, "수량");

Integer price = input(scanner, "가격");

String link;
do {
System.out.print("구매링크: ");
link = scanner.nextLine();
} while (!StockValidator.check(link));

boolean result = itemStore.saveItem(name, item, quantity, price, link);
System.out.println(result ? "성공적으로 신청되었습니다." : "신청에 실패했습니다.");
}

private void handleView() {
Item[] i = itemStore.getItems();
if (i.length == 0) {
System.out.println("신청된 물품이 없습니다.");
} else {
for(Item item : i){
System.out.println(item.getItem());
}
}
}

private static Integer input(Scanner sc, String st) {
while (true){
System.out.printf("%s: ", st);
try {
Integer i = sc.nextInt();
sc.nextLine();
return i;
} catch(InputMismatchException e){
System.out.println("입력이 올바르지 않습니다.");
sc.nextLine();
}
}
}
}

class Item{
private final String name;
private final String item;
private final Integer quantity;
private final Integer price;
private final String link;

public Item(String name, String item, Integer quantity, Integer price, String link) {
this.name = name;
this.item = item;
this.quantity = quantity;
this.price = price;
this.link = link;
}

public String getItem() {
return String.format(
"신청자: %s, 물품명: %s, 수량: %d, 가격: %d, 구매링크: %s",
name, item, quantity, price, link
);
}
}

class StockValidator {
public static boolean check(String link){
if (!link.startsWith("http://") && !link.startsWith("https://")){
System.out.println("올바른 링크를 입력해주세요.");
return false;
} else if (!link.contains("11st.co.kr") && !link.contains("coupang.com")) {
System.out.println("11번가 또는 쿠팡 링크만 가능합니다.");
return false;
} else {
return true;
}
}
}

interface ItemStore {
Item[] getItems();
int getSize();
boolean isFull();
}

class Store implements ItemStore {
private final Item[] items = new Item[5];
private Integer size = 0;

public boolean saveItem(Item item) {
if(this.isFull()) return false;
items[size++] = item;
return true;
}

public Item[] getItems() {
Item[] temp = new Item[size];
System.arraycopy( items, 0, temp, 0, size );
return temp;
}

public int getSize() {
return size;
}

public boolean isFull() { return size >= items.length; }
}

class Items implements ItemStore {
private final Store store;

Items(Store store) {
this.store = store;
}

public boolean saveItem(String name, String item, Integer quantity, Integer price, String link) {
Item i = new Item(name, item, quantity, price, link);
return store.saveItem(i);
}

public Item[] getItems() {
return store.getItems();
}

public int getSize() {
return store.getSize();
}

public boolean isFull() {
return store.isFull();
}
}