https://techblog.woowahan.com/2502/
저번 로또를 작성하면서 내 한계를 느끼고 객체지향 관련 찾아보다가 최고의 설명을 찾았다.
이번엔 위 내용을 토대로 배운 것을 활용해보려고 한다.
https://github.com/woowacourse/java-racingcar-precourse
문제 설명이다.
객체지향적으로 바라보고 설계하고 구현하자
1. 객체들로 구성된 작은 세상으로 바라보자
일단 객체를 사용자, 게임기, 자동차, 자동차 이용자 총 4개로 분리시켰다.
2. 객체들 간의 관계
사용자는 게임기에서 자동차 이용자와 라운드 횟수를 입력을 할 수 있다
게임기는 자동차 이용자에게 자동차를 부여할 수 있다.
또 게임을 시작시켜서 라운드 횟수만큼 진행시킬 수 있다.
3. 객체들의 분류
- 사용자 객체는 ‘사용자 타입’의 인스턴스
- 게임기 객체는 ‘게임기 타입’의 인스턴스
- 자동차 이용자 모두 ‘자동차 이용자 타입’의 인스턴스
- 자동차 객체는 ‘자동차 타입’의 인스턴스
4. 타입 간의 관계
게임기 ------- 자동차이용자 - 자동차
|
사용자
5. 객체지향 설계
객체지향의 세계는 협력하는 자율적인 객체들의 공동체
설계하고 구현하기
사용자 ----> 게임기
자동차 이용자 및 게임횟수를 입력하라
결과를 알려줘라
게임기 ---->자동차이용자
자동차 이용자를 생성해라
자동차 이용자를 각 자동차에 넣어서 반환한다
자동차이용자 ----> 자동차
각 이용자를 자동차에 넣어라
자동차를 반환한다
처음에 차량 객체를 생성한다.
이름하고 위치 값을 저장한다.
package racingcar.model;
public class Car { //자동차 객체 생성
private String name;
private int position = 0;
public Car(String name, int position) {
this.name = name;
this.position = position;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPosition() {
return position;
}
public void setPosition(int position) {
this.position = position;
}
}
다음은 게임기 클래스다.
package racingcar.model;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class RacingGame {
public List<Car> saveCars(String[] carNames) {
List<Car> cars = new ArrayList<>();
for (int i = 0; i < carNames.length; i++) {
String name = carNames[i];
cars.add(new Car(name, 0));
}
return cars;
}
public void updatePhase(List<Car> cars) {
Random random = new Random();
for (int j = 0; j < cars.size(); j++) {
int randomNum = random.nextInt(10);
if (randomNum >= 4) {
cars.get(j).setPosition(cars.get(j).getPosition() + 1);
}
}
}
}
간단히 자동차 이용자 이름을 받아 차량안에 넣어주는 메서드와 랜덤하게 값을 증가시켜주는 메서드다.
그다음은 게임 결과를 보여주는 클래스다.
package racingcar.model;
import java.util.List;
import java.util.Random;
public class WinningResult {
public int winningScore = 0;
public void winningScore(List<Car> cars) {
for (int m = 0; m < cars.size(); m++) {
if (winningScore < cars.get(m).getPosition()) {
winningScore = cars.get(m).getPosition();
}
}
}
}
제일 큰녀석이 winningScore에 삽입
다음은 입력받는 메서드다.
package racingcar.view;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class InputView { //입력관련 메서드 집합
Scanner sc = new Scanner(System.in);
public String[] getNames() {
System.out.print("경주할 자동차 이름을 입력하세요.(이름은 쉼표(,) 기준으로 구분)");
String inputname = sc.next();
String[] names = inputname.split(","); //쉼표로 분리해서 넣기
try {
nameRange(names); //글자가 5개 이상이거나,
sameName(names); //같은 이름이 있을 경우
} catch (IllegalArgumentException e) {
getNames();
}
return names;
}
private void nameRange(String[] names) {
for (String name : names) {
if (name.length() > 5) {
System.out.print("글자가 5자리 아래여야만함");
throw new IllegalArgumentException();
}
}
}
private void sameName(String[] names) {
List<String> check = new ArrayList<>();
for (String name : names) {
if (check.contains(name)) {
System.out.print("중복이름 X");
throw new IllegalArgumentException();
} else {
check.add(name);
}
}
}
public int getRound() {
System.out.print("시도할 회수는 몇회인가요?");
String inputround = sc.next();
int round = 0;
try {
round = Integer.parseInt(inputround);
} catch (IllegalArgumentException e) {
System.out.print("숫자나 입력하세여");
getRound();
}
return round;
}
}
다음은 출력 메서드다.
package racingcar.view;
import racingcar.model.Car;
import java.util.ArrayList;
import java.util.List;
public class OutputView {
public void round(List<Car> cars) {
for (Car car : cars) {
System.out.print(car.getName());
System.out.print(" : ");
System.out.println("-".repeat(car.getPosition()));
}
System.out.println();
}
public void result(List<Car> cars, int firstPrize) {
System.out.print("");
List<String> winner = new ArrayList<>();
for (int n = 0; n < cars.size(); n++) {
if (cars.get(n).getPosition() == firstPrize) {
winner.add(cars.get(n).getName());
}
}
System.out.println(String.join(", ", winner));
}
}
자동차 모양 나오기 & 우승한 사람 winner에 저장한 뒤 출력하는 메서드
마지막은 전체적은 흐름을 관리하는 Controller부분이다.
package racingcar.controller;
import racingcar.model.Car;
import racingcar.model.RacingGame;
import racingcar.model.WinningResult;
import racingcar.view.InputView;
import racingcar.view.OutputView;
import java.util.List;
public class RacingController {
private final RacingGame racinggame = new RacingGame();
private final WinningResult winningresult = new WinningResult();
private final InputView inputView = new InputView();
private final OutputView outputview = new OutputView();
public void start() {
String[] names = inputView.getNames();
int round = inputView.getRound();
List<Car> cars = racinggame.saveCars(names);
roundResult(round, cars);
winningresult.winningScore(cars);
outputview.result(cars, winningresult.winningScore);
}
private void roundResult(int round, List<Car> cars) {
System.out.println("");
for (int i = 0; i < round; i++) {
racinggame.updatePhase(cars);
outputview.round(cars);
}
}
}
보면 시작해서 입력, 결과호출, 결과출력까지 관장하는 메서드다.
객체지향 생활 체조 9가지 원칙
객체지향 생활 체조 원칙을 지키면서 공부하자.
'백엔드' 카테고리의 다른 글
[Spring Boot] JPA @Id 전략 (0) | 2024.08.15 |
---|---|
[Spring Boot] 디렉터리 패키지 구조 - 도메인형, 계층형 (0) | 2024.08.11 |
[Spring Boot] IoC, DI, AOP 정리 (0) | 2024.08.11 |
[Spring Boot] Mapping 종류 (0) | 2024.08.11 |
로또 - 객체지향 (1) | 2024.03.18 |