day38 🌕

장미·2022년 7월 21일
0

오늘의 성과

목록 보기
38/129

스프링 MVC 1편 - 백엔드 웹개발 핵심기술 섹션 6 마저 듣기

+) 22. 07. 23. day37 🌕 에 추가 완료!


베이스볼 이어서 하기 ❤️

+) 22. 07. 22. 01:10 일단... 첫 pr 올림...^^ 내가 봐도 코드 더러움. 그래도 일단 기록한다...


Input Class
사용자에게 값을 입력 받는 클래스

public class Input {
    private ArrayList<Integer> numbers = new ArrayList<>();

    public ArrayList<Integer> input() {
        clear();
        System.out.println("\n" + "숫자 3개를 입력해 주세요. (예: 123)");
        String[] number = inputData();

        while (checkForDuplicates(number) == true || checkForLength(number) == true) {
            System.out.println("\n" + "입력값은 중복이 없어야 하며 3자리여야 합니다. 재입력해 주세요.");
            number = inputData();
        }

        for (int i = 0; i < 3; i++) {
            numbers.add(Integer.parseInt(number[i]));
        }

        return numbers;
    }

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

    public String[] inputData() {
        return new Scanner(System.in).nextLine().split("");
    }

    private static boolean checkForLength(String[] nums) {
        return nums.length > 3 || nums.length < 3;
    }

    private static boolean checkForDuplicates(String[] nums) {
        Long count = Stream.of(nums).distinct().count();
        return nums.length != count;
    }
}
  • input()
    입력 받은 문자열을 하나씩 분리해 배열 number에 넣는다.
    값에 중복이 있는지, 3글자가 맞는지 검사한 후 이를 만족하지 못하면 재입력 받는다.
    배열에 있는 값을 정수로 변환한 뒤 리스트에 넣고 반환한다.

  • clear()
    리스트를 초기화한다.

  • inputData()
    값을 입력 받고 한 글자씩 분리한다.

  • checkForLength(String[] nums)
    문자열의 길이가 3인지 검사한다. 만약 3이 아닐 경우 true를 반환한다.

  • checkForDuplicates(String[] nums)
    중복값이 있는지 검사한다. 만약 중복값이 있을 경우 true를 반환한다. (배열의 총 개수와 중복값을 걸러낸 개수 비교)


RandomNumber Class
랜덤한 정수를 생성하는 클래스

public class RandomNumber {

    private static final Set<Integer> randomNumbersSet = new HashSet<>();

    public ArrayList<Integer> createRandomNumber() {

        while(randomNumbersSet.size() < 3) {
            randomNumbersSet.add((int) (Math.random() * 9 + 1));
        }

        ArrayList<Integer> randomNumbers = new ArrayList<>(randomNumbersSet);
        return randomNumbers;
    }
}
  • createRandomNumber()
    중복값이 없도록 Set으로 값을 저장한다. 리스트에 3개가 들어갈 때까지 반복해서 랜덤값을 생성하고 넣는다.

Comparison Class
사용자가 입력한 값과 랜덤 생성한 값을 비교하는 클래스

public class Comparison {
    int ball;
    int strike;

    public int compareNumber(ArrayList<Integer> input, ArrayList<Integer> randomNumber) {
        ball = 0;
        strike = 0;

        for (int i = 0; i < 3; i++) {
            if (input.contains(randomNumber.get(i))) {
                ball++;
            }

            if (input.get(i).equals(randomNumber.get(i))) {
                ball = 0;
                strike++;
            }
        }

        Output output = new Output();
        output.output(strike, ball);

        return strike;
    }
}
  • compareNumber(ArrayList<Integer> input, ArrayList<Integer> randomNumber)
    만약 입력 값과 랜덤값 중 순서 상관없이 겹치는 값이 있다면 ball을 하나 늘린다.
    순서도 같이 겹치는 값이 있다면 strike를 하나 늘린다.

Output Class
결과를 출력하는 클래스

public class Output {
    public void output(int strike, int ball) {
        if(strike == 3) {
            System.out.println("BASEBALL WIN~!");
            return;
        }

        System.out.println();
        System.out.println(ball + "ball");
        System.out.println(strike + "strike");
    }
}
  • output(int strike, int ball)
    strike와 ball 값을 받아와, 만약 strike가 3이면 답을 맞힌 것이므로 BASEBALL WIN~!을 출력한다.
    정답을 맞히지 못했다면 ball, strike 여부를 알려준다.

Main Class
실행하는 클래스

public class Main {
    public static void main(String[] args) {
        System.out.println("Play Baseball Game");

        Input input = new Input();
        RandomNumber randomNumber = new RandomNumber();
        Comparison compareNumber = new Comparison();

        while (compareNumber.compareNumber(input.input(), randomNumber.createRandomNumber()) != 3) {

        }
    }
}

결과는 잘 나오는데 while문이... 너무 더럽다.
main에 있는 텅 빈 while문이랑 input에 있는 유효성 검사;; 너무 보기 안 좋음.
그리고 Input 클래스에 뭐가 너무 많아... 원래 저렇게 많으면 안 되는데;; 어떻게 리팩토링 해야 할지 감이 안 잡힘. 총체적 난국이다.


토픽 - Spring MVC 정리 끝내기

+) 22. 07. 24. day37 🌕 에 추가 완료!


토픽 - Spring 시작하기

+) 22. 07. 24. 추가

스프링

스프링은 자바 언어 기반의 프레임워크이며, 객체 지향 언어가 가진 강력한 특징을 살려낸다. 즉, 스프링은 좋은 객체 지향 애플리케이션을 개발할 수 있게 도와주는 프레임워크다.

의존성 주입(DI)제어 역전(IoC), 관점 지향 프로그래밍(AOP) 요소를 통해 느슨한 결합(Loose Coupling)을 달성할 수 있게 해준다. 이렇게 느슨한 결합으로 개발한 애플리케이션은 단위 테스트를 수행하기 용이하다는 장점이 있다.


의존성 주입(DI, Dependency Injection)

⬇️ DI를 사용하지 않은 코드의 경우

@RestController
public class NoDIController {
	private MyService service = new MyServiceImpl();
	
	@GetMapping("/hello")
	public String getHello() {
		return service.getHello();
	}
}

Controller는 ‘MyService’ 객체에 의존하게 된다.
객체의 인스턴스를 얻게 되면 객체 간의 결합도가 올라가고, 이런 코드 작성은 단위 테스트를 위해 Mock 객체(가짜 객체)를 사용할 수 없게 된다.

⬇️ DI를 사용한 코드의 경우

@Service
public class MyServiceImpl implements MyService {
	@Override
	public String getHello() {
		return "Hello";
	}
}

@RestController
public class DIController {
	MyService myService;

	@Autowired
	public DIController(MyService myService) {
		this.myService = myService;
	}

	@GetMapping("/hello")
	public String getHello() {
		return myService.getHello();
	}
}

@Service, @Autowired 어노테이션을 통해 MyService의 인스턴스를 가진다.
위와 같이 코드를 작성하면 단위 테스트 상황에서 Service 객체를 Mock 객체로 대체하여 쉽게 테스트 할 수 있다.

관점 지향 프로그래밍(AOP, Aspect Oriented Programming)

스프링 프레임워크에서 제공하는 강력한 기능 중 하나이다.
AOP는 쉽게 말해 OOP(객체 지향 프로그래밍)를 보완하는 수단으로, 여러 곳에 쓰이는 공통 기능을 모듈화하여 필요한 곳에 연결함으로써 유지보수 또는 재사용에 용이하도록 하는 것을 의미한다.
AOP를 통해 기존 프로젝트에 로직 수정 없이 다양한 기능을 추가할 수 있으며, 이러한 개발 방식을 통해 결합도를 낮춘 개발이 가능해진다.


스프링이란 단어는 문맥에 따라 다르게 사용된다.

  • 스프링 DI 컨테이너 기술
  • 스프링 프레임워크
  • 스프링 부트, 스프링 프레임워크 등을 모두 포함한 스프링 생태계

스프링 프레임워크

  • 핵심 기술: 스프링 DI 컨테이너, AOP, 이벤트, 기타
  • 웹 기술: 스프링 MVC, 스프링 WebFlux
  • 데이터 접근 기술: 트랜잭션, JDBC, ORM 지원, XML 지원
  • 기술 통합: 캐시, 이메일, 원격접근, 스케줄링
  • 테스트: 스프링 기반 테스트 지원
  • 언어: 코틀린, 그루비

최근에는 스프링 부트를 통해 스프링 프레임워크의 기술들을 편리하게 사용할 수 있다.


스프링 부트

스프링은 다양한 기능을 제공하고 있지만, 그 기능을 사용하기 위한 설정에 많은 시간이 걸린다. (예: Hibernate Datasource, Entity Manager 등)
그래서 스프링을 좀 더 빨리, 편하게 사용할 수 있도록 나온 것이 바로 스프링 부트이다.
스프링 부트는 스프링을 편리하게 사용할 수 있도록 지원하며, 최근에는 기본으로 사용한다.

스프링 부트가 제공하는 기능
스프링 부트는 자동 설정(Auto Configuration)을 이용한다.

  • 애플리케이션 개발에 필요한 모든 Dependency를 프레임워크에서 관리한다. (호환되는 버전을 자동으로 관리해 준다.)
  • jar 파일이 클래스 패스에 있는 경우 스프링 부트는 Dispatcher Servlet으로 자동 구성된다.
  • 스프링 부트는 미리 설정되어 있는 Starter 프로젝트를 제공한다.
  • xml 설정 없이 자바 코드를 통해 설정할 수 있다.

스프링 부트 프로젝트의 의존성 관리

  • spring boot starter dependency를 통해 다양한 패키지를 수용한다.
  • 이를 통해 개발자는 dependency 관리(호환성 체크 등)에 대해 고려할 필요가 없어졌다.

장점

  • 단독으로 실행할 수 있는 스프링 애플리케이션을 쉽게 생성
  • 톰캣 같은 웹 서버를 내장해서 별도의 웹 서버를 설치하지 않아도 됨
  • 손쉬운 빌드 구성을 위한 starter 종속성 제공
  • 스프링과 3rd parth(외부) 라이브러리 자동 구성
  • 메트릭, 상태 확인, 외부 구성 같은 프로덕션 준비 기능 제공
  • 관례에 의한 간결한 설정

참고 자료

  1. 어라운드허브 스튜디오, “'스프링'과 '스프링 부트'의 차이”, https://youtu.be/YSsl5-q2BR4
  1. 김영한, “스프링이란”, https://youtu.be/xs44Ty_Kerk

함께 보면 좋은 자료

  1. 우아한Tech, “[10분 테코톡] 🦊닉의 Spring vs Spring Boot”, https://youtu.be/6h9qmKWK6Io

  2. 뉴렉처, “스프링 프레임워크 강의 1강 - Spring 소개와 학습 안내”, https://youtu.be/XtXHIDnzS9c

  3. 뉴렉처, “스프링 프레임워크 강의 2강 - 느슨한 결합력과 인터페이스”, https://youtu.be/KJ9Rus3QfUc


기타 짜잘이들 처리

profile
김뉴비

0개의 댓글

관련 채용 정보