본문 바로가기

study/Back-end

[Back-end/Spring] 스터디 2주차 정리

진도 : 자바(섹션 2-객체) + 스프링 입문(섹션 3)

자바 프로그래밍 입문 강좌 - https://www.inflearn.com/course/실전-자바_java-renew
스프링 입문 - https://www.inflearn.com/course/스프링-입문-스프링부트

Q. MVC 패턴과 컨트롤러 / 서비스 / 리포지토리 / 도메인의 차이?

MVC 패턴은 개발 방법론 (디자인 패턴의 한 종류)

컨트롤러 / 서비스 / 리포지토리 / 도메인은 웹 애플리케이션 계층 구조

전자는 이렇게 하면 더 효율적일 것이다 ~ 이고 후자는 이렇게 구성이 되어야만 한다.

 

Q. MVC 패턴에서 View는 프론트엔드와 무엇이 다른가?

백엔드에서도 각 데이터를 다루고 이를 결국 HTML/CSS/JS와 같은 언어로 사용자가 볼 수 있도록 만들어야 한다.

따라서 프론트엔드가 요청한 데이터를 벡엔드에서 View로 보여주는 것이 아닐까?

프론트엔드가 디자인하고 만들어놓은 블록에 벡엔드에서 데이터를 받아서 넣는 느낌으로 이해함

 

Q. 느슨한 결합에서 같은 객체를 사용해도 되는 이유?

회원가입 한 정보와 로그인을 할 때 확인하는 정보 모두 동일 - 같은 repo를 써도 상관없다.

즉, 이렇게 동일한 객체를 사용할 때 새로 객체를 할당받지 않고, 매개변수로 받아서 저장해 사용하는 것이 아닐까 싶다.

 

Q. 인터페이스 상속 vs 클래스의 상속?

이 얘기를 할 때 인터페이스와 추상 클래스라는 개념이 모호해서 조금 더 이해하기 어려웠던 것 같다.

그러다 보니 얘기가 인터페이스 vs 추상 클래스 라기보다는 인터페이스와 클래스의 상속이 어떻게 다른지에 대해 얘기한 것 같다.

부모 클래스를 자식 클래스가 상속받았을 때에는 상속받은 메서드 + 추가적으로 내가 선언하는 메서드

인터페이스는 명세서와 같은 느낌이기 때문에 선언만 되어있는 메서드 하지만 무조건 재정의해야 하는 메서드

이기 때문에 상속받은 것보다 오히려 자유롭게 메서드를 작성 가능

추상 클래스는 클래스 모든 기능 + 구현되지 않은 선언 메서드(인터페이스 기능)

공통된 기능이 필요할 시 추상 클래스를 이용해 일반 메서드를 작성하여 자식 클래스가 사용할 수 있도록 하면 된다.

만약 인터페이스로 구현하면 공통으로 필요한 기능들을 모두 오버라이딩 하여 사용해야 함

(인터페이스에서 디폴트 메서드가 예외로 적용될 수 있을 듯)

추상 클래스는 클래스처럼 단일 상속만 가능

인터페이스는 인터페이스 여러 개의 각각의 기능을 모두 구현함으로써 각 인터페이스 타입을 모두 가질 수 있음

-> 객체가 다양한 자료형(타입)을 가질 수 있음 - 다형성

 

Q. Optional에서는 NPE(NullPointerException)를 유발할 수 있는 null을 체크할 필요가 없다?

 

Optional안의 isPresent의 함수를 사용하면 null인지 검사를 하는 것이 아닌가?

 

null을 체크를 하는 것보다 명시적으로 해당 변수가 null일수도 있다는 가능성을 표현하는 역할이 제일 클 것 같다.

이렇게 되면 불필요한 방어 로직을 줄일 수 있다.

 

 

Optional <T>는 null 값이 올 수 있는 값을 감싸는 Wrapper클래스 (각종 메서드 제공)

Optional 클래스는 아래와 같은 value에 값을 저장 -> 값이 null이더라도 바로 NPE가 발생하지 않도록 도와준다.

 

public final class Optional<T> {

  // If non-null, the value; if null, indicates no value is present
  private final T value;

  ...
}

 

메서드의 반환 값이 절대 null이 아니라면 Optional을 사용하지 않는 것이 좋다.

즉, Optional은 메소드의 결과가 null이 될 수 있으며, null에 의해 오류가 발생할 가능성이 매우 높을 때 반환 값으로만 사용되어야 한다. 

Optional.of() //값이 Null이 아닌 경우
Optional.ofNullbale() // 값이 Null일수도, 아닐수도 있는 경우

 

Optional <T> 설명 출처: https://mangkyu.tistory.com/70[MangKyu's Diary:티스토리] 

 


아래의 개념 공부는 각 출처의 글을 정리하여둔 것

MVC 패턴

아래의 컨트롤러 / 서비스 / 리포지토리 / 도메인 부분에서 컨트롤러는 MVC 패턴의 컨트롤러와 동일한 역할이라고 하기에

먼저 MVC 패턴에 대해 공부하였다.

 

 

[Spring] MVC 패턴 (ORM, SQL) - 회고

Spring 프레임워크로 간단한 웹 서버를 구현해 보고있다. 처음으로 JPA를 사용해봤고 정리해봤다. https://geonoo.tistory.com/147?category=1077864 [Spring] Java Persistence API - JPA Java Persistence API(..

geonoo.tistory.com

  • Model, View, Controller의 약자
  • 하나의 애플리케이션, 프로젝트를 구성할 때 그 구성요소를 세 가지 역할로 구분한 패턴
  • 역할에 따른 분리로 인해 유지보수성, 확장성, 유연성 증가, 코드 중복이 사라짐

사용자가 웹 브라우저를 통해 URL 호출 → Controller에서 요청을 받고 그 안에서 로직이나 데이터가 필요하다면 Model에서 호출 → 모델에 구성된 로직이나 데이터베이스에 접근해서 데이터를 가져옴

 

  • model
    • DB와 연동하여 사용자의 입출력 데이터를 내부 로직으로 처리하는 역할
    • 데이터 추출, 저장, 삭제, 업데이트
    • 데이터와 연관된 비즈니스 로직 처리
  • Controller
    • model과 view 사이를 이어주는 인터페이스 역할
    • 쉽게 말해 사용자가 접근한 URL에 따라 사용자의 요청사항을 파악 후 그 요청에 맞는 데이터를 model에게 의뢰 → 데이터를 view에 반영해서 사용자에게 알려주는 역할
  • View
    • 클라이언트 측 기술(HTML, CSS, JS)들을 모아둔 컨테이너
    • 사용자가 볼 결과물을 생성하기 위해 모델로부터 정보를 얻어와 화면으로 출력

컨트롤러 / 서비스 / 리포지토리 / 도메인

 

 

[Spring] 웹애플리케이션 계층구조

Controller클라이언트가 이용할 앤드포인트클라이언트의 요청을 어떻게 처리할 지 정의화면에서 넘어오는 매개변수를 이용해 서비스 객체를 호출하는 역학Service비즈니스 로직 구현Http 통신을 위

velog.io

 

 

Spring Controller , Service , Repository , Domain , DTO

= Spring Controller , Service , Repository , Domain , DTO = - Controller - Client의 요청을 받았을 때 그 요청에 대해 실제 업무를 수행하는 Service를 호출 클라이언트가 보낸 데이터가 있다면 Service..

plo-developdiary.tistory.com

 

  • 컨트롤러
    • 웹 MVC의 컨트롤러 역할
    • Client의 요청을 어떻게 처리할지 정의하고, 서비스의 객체를 호출하는 역할
    • 서비스에서 실질적으로 처리한 내용을 다시 controller가 받은 후 지정된 뷰에 모델 객체를 넘겨줌
    • 클라이언트가 보낸 데이터가 있다면 Service를 호출할 때 전달하기 쉽게 데이터 가공
  • 서비스
    • 핵심 비즈니스 로직 구현
    • Repo에서 DB에 자료를 가져오게 되면 이를 컨트롤러에 전달하는 역할
    • 데이터베이스 영역과 도메인 영역을 연결해주는 매개체
  • 리포지토리
    • 데이터베이스에 접근, 도메인 객체를 DB에 저장하고 관리
    • DB에 직접 접근
    • Domain 객체를 DB에 저장하고 관리
  • 도메인
    • 비즈니스 도메인 객체
    • DB의 테이블과 매핑되어 Entity class라고도 부른다.
    • 실제 DB에 저장되는 내용들을 구현하는 class
    • 예) 회원, 주문, 쿠폰 등등 주로 데이터베이스에 저장하고 관리됨

DI(Dependency Injection)

 

[Spring] DI(Dependency Injection)를 사용하는 이유

Spring boot에서 DI를 사용하게된 이유를 알려면 강한결합과 느슨한결합에 대해서 알아야한다. 강합결합과 느슨한결합 중 강한 결합은 문제가 있는데, 어떤 문제인지 예제를 통해서 알아보면 먼저

geonoo.tistory.com

 

  • 강한 결합 - 유지보수가 어려운 상태
    • Controller에서 Service를 생성 → Service에서 Repo를 생성하여 사용

→ 이를 해결하기 위해

  • 각 객체에 대한 객체 생성은 딱 1번만
  • 생성된 객체를 모든 곳에서 재사용
  • 느슨한 결합
    • Repo에서 생성된 객체를 Service에서 재사용해서 Service를 생성 → 다시 Controller에서 Service를 재사용

 

IoC(Inversion of Control): 제어의 역전

  • 프로그램의 흐름이 뒤바뀜
    • 강한 결합: Controller → Service → Repository
    • 느슨한 결합: Repository -> Service -> Controller

이렇게 용도에 맞게 객체를 그냥 가져다 사용하는 것을 DI라고 함

인터페이스

 

[JAVA] 자바 인터페이스란?(Interface)_이 글 하나로 박살내자

1. 인터페이스 개념과 역할 인터페이스....이 글하나로 박살내자. (회사에서 존댓말을 많이 쓰기때문에 여기서라도 반말로 글을 써보고 싶음 ㅎ) 인터페이스는 뭘까?? 결론부터 말하면, 극단적으

limkydev.tistory.com

 

  • 극단적으로 동일한 목적 하에 동일한 기능을 수행하게끔 강제하는 것
  • 자바의 다형성을 극대화하여 개발코드 수정을 줄이고 프로그램 유지보수성을 높이기 위해 인터페이스를 사용
public interface 인터페이스명{

//상수
타입 상수명 = 값;

//추상 메소드
타입 메소드명(매개변수, ...);

//디폴트 메소드
default 타입 메소드명(매개변수, ...){
    //구현부
}

//정적 메소드
static 타입 메소드명(매개변수){
    //구현부
}

}
  • 상수 (절대적)
    • 인터페이스에서 값을 정해줄 테니 함부로 바꾸지 말고 제공해주는 값만 참조
  • 추상 메서드 (강제적)
    • 가이드만 줄 테니 추상 메서드를 오버 라이딩해서 재구현
  • 디폴트 메서드 (선택적)
    • 인터페이스에서 기본적으로 제공해주지만, 맘에 안 들면 각자 구현해서 써라
  • 정적 메서드 (절대적)
    • 인터페이스에서 제공해주는 것으로 무조건 사용
  • 예시 Bank 인터페이스
    • 상수 : MAX_INTEGER
    • 추상 메서드 : withDraw, deposit
      • 각 은행에서 오버 라이딩해서 재구현을 해야 함
      • 이를 implements한 모든 클래스에서 강제적으로 추상 메서드를 구현해야 함
      • 구현하지 않을 시 전부 에러
    • 정적 메서드 : BCAuth
      • 무조건 제공해주는 메서드를 사용해야 함
      • 오버 라이딩할 수 X, 그냥 가져다가 써야 함
    • 디폴트 메서드 : findDormancyAccount
      • 이미 운영되고 있는 시스템에서 추가 요건으로 인해 불가피하게 반영을 해야 할 때 사용하면 효과적
      • 디폴트 메서드를 정의하고 기본 구현부를 제공하고 만약 기본 구현부가 마음에 들지 않는다면 각자가 오버라이딩을 하여 재구현할 수 있도록 선택적인 메소드를 가이드
      public interface Bank {
      
        //상수 (최대 고객에게 인출해 줄 수 있는 금액 명시)
        public int MAX_INTEGER = 10000000;
      
        //추상메소드(인출하는 메소드)
        void withDraw(int price);
      
        //추상메소드(입금하는 메소드)
        void deposit(int price);
      
        //JAVA8에서 가능한 defualt 메소드(고객의 휴면계좌 찾아주는 메소드 : 필수구현은 선택사항)
        default String findDormancyAccount(String custId){
            System.out.println("**금융개정법안 00이후 고객의 휴면계좌 찾아주기 운동**");
            System.out.println("**금융결제원에서 제공하는 로직**");
            return "00은행 000-000-0000-00";
        }
      
        //JAVA8에서 가능한 정적 메소드(블록체인 인증을 요청하는 메소드)
        static void BCAuth(String bankName){
            System.out.println(bankName+" 에서 블록체인 인증을 요청합니다.");
            System.out.println("전 금융사 공통 블록체인 로직 수행");
        }
      
      
  • 대한민국에서 은행 사업을 하려면 Bank라는 인터페이스 가이드에 맞게 구현해야 한다고 가정
}
```

- KB 은행
    - 디폴트 메소드 : findDormancyAccount를 재구현하지 않음

    → 제공 메소드를 사용, 혹은 아직 사용하지 않겠다.


```java
public class KBBank implements Bank{

    @Override
    public void withDraw(int price) {
        System.out.print("KB은행만의 인출 로직...");
        if(price < Bank.MAX_INTEGER){
            System.out.println(price+" 원을 인출한다.");    
        }else{
            System.out.println(price+" 원을 인출실패.");    
        }
    }

    @Override
    public void deposit(int price) {
        System.out.println("KB은행만의 입금 로직..."+price+" 원을 입금한다.");

    }

}
```

- SH 은행
    - 디폴트 메소드를 재정의하여 SH은행사만의 로직을 재구현

```java
public class SHBank implements Bank{

    @Override
    public void withDraw(int price) {
        System.out.println("SH은행만의 인출 로직...");
        if(price < Bank.MAX_INTEGER){
            System.out.println(price+" 원을 인출한다.");    
        }else{
            System.out.println(price+" 원을 인출실패.");
        }
    }

    @Override
    public void deposit(int price) {
        System.out.println("SH은행만의 입금 로직..."+price+" 원을 입금한다.");
        System.out.println("SH은행은 별도의 후행처리 작업을 따로 한다.");

    }

    //JAVA8에서 가능한 defualt 메소드(고객의 휴면계좌 찾아주는 메소드)
    @Override
    public String findDormancyAccount(String custId){
        System.out.println("**금융개정법안 00이후 고객의 휴면계좌 찾아주기 운동**");
        System.out.println("*SH은행만의 로직 적용*");
        return "00은행 000-000-0000-00";
    }

}
```

[[JAVA] 자바 인터페이스란?(Interface)_이 글 하나로 박살내자](https://limkydev.tistory.com/197)