220304~5 - TIL (배역과 배우를 구별하자!)

Suntory(SY Kim)·2022년 3월 5일
0

TIL

목록 보기
43/58

✅ 한 일

  • 스프링 미션하기
  • 스프링 강의 수강
  • 알고리즘 스터디 문제 풀이
  • 기타 학습

📝 배운 것들

금요일

스프링 미션 5일차

오전에는 영한님 핵심 원리 강의를 들었습니다.
들으면서 의존성 주입을 왜 해야하는 지에 대해서 들었습니다. 처음에는 기능 클래스에서 자기가 사용할 인터페이스의 구현체를 정의해서 사용했습니다. 예를들어,

OrderService orderService = new OrderServiceImpl();

와 같이 입니다. 이렇게 되면, 위 클래스는 인터페이스인 OrderService뿐만 아니라, 구현체인 OrderServiceImpl에도 의존하게 됩니다. 이렇게 되면, 구현체를 바꿔야할 때 OCP를 위반하게 됩니다.

그러므로, 관점을 바꿔야 합니다.

연극을 예시로 들면, 연극은 배역이라는 역할과 배우라는 구현이 존재합니다. 어떤 배우가 상대 배우와 대사(메시지)를 주고 받기 위해 자신의 머릿속에 상대 배우를 기록해야 합니다.

그런데, 잘 생각해보면 어떤 배우가 기억해야할 것은 상대 배우일까요, 배역일까요? 잘 생각해보면 배역임을 알 수 있습니다. 물론 이미 그 배역을 맡을 상대 배우가 정해진 경우도 있을 것입니다. 하지만 그 배역을 맡은 배우가 바뀐다고 해서 이 배우가 대사를 주고받을 수 없게 된다면, 현실적으로 매우 부자연스럽습니다.

최근에 유퀴즈에서 조세호씨가 코로나 확진이 되면서 침착맨이 보조 mc로 출연했던 적이 있습니다. 유재석씨 입장에서는 보조 mc의 역할을 맡는 구현체인 조세호씨가 침착맨으로 바뀌었지만 진행하는 데에는 아무 지장이 없었습니다.

이처럼 어느 클래스가 기억해야할 것은 구현이 아니라 역할이라는 것을 알 수 있습니다. 이렇게 해야만 OCP를 지킬 수 있습니다.

돌고 돌아서, 위와 같이 한 클래스에서 배역배우를 모두 정하였기 때문에 OCP를 지킬 수 없었습니다. 이를 해결하기 위해서는 각 클래스에서는 역할(배역)만 기억하고 구현(배우)주입(캐스팅)해줄 클래스가 필요합니다.

그래서 예제에서는 AppConfig라는 클래스를 만들어, 의존성을 주입해줄 수 있도록 하였습니다. 당연하게도, 구현체가 바뀌면 이 클래스의 코드는 바뀌어야 합니다. 하지만 실제 기능 클래스에서는 아무 코드도 수정할 필요가 없어집니다.


오후에는 미션 2를 이어서 구현했습니다. 회원정보를 수정하는 부분을 공부했는데, 기능은 구현됐지만 고민이 많이 되는 부분이 있었습니다. 아직도 다음과 같은 사항을 공부해야겠다고 느꼈습니다.

  • DTO의 정확한 의의?
  • Service, Repository와 같은 각 Layer가 져야 할 적절한 책임
    (간단한 검증로직이 Repository에 존재해도 괜찮은가? 등의 고민)
  • View에 리턴해줄 때에도 모델과의 의존성을 제거하기 위해 DTO로 처리해야 하는데 안하고 있는 것에 대한 문제의식

토요일

숙취가 심해서 거의 하루를 날리고 자정 무렵에 조금이나마 공부를 했습니다..

알고리즘 풀기

1주차 마지막 날에 제가 출제한 문제를 풀었습니다. 난이도는 실버1이지만 낯선 개념이다보니 꽤나 시간이 오래 걸렸습니다. 이번 스터디를 하면서 벌써 낯선 알고리즘 개념의 키워드를 많이 학습해서 좋았습니다.

  • 파라메트릭 서치
  • 누적 합 개념
  • prefix sum
  • 세그먼트 트리(이건 아직 스터디에서 다루지 않았지만 숙원사업이라 적어봤습니다..)
  • DP(역시 다루지 않았지만 안 푼지 오래돼서 추후 다뤄보고 싶어서 적어보았습니다..)

갑자기 자료형 공부

위 알고리즘을 풀다가 갑자기 바킹독님의 강의 중에 뭔가 참고할 게 있었던 거 같아서 보게 되었습니다. 그러다 후반부에 정수 자료형/ 실수 자료형에 대해서 보았는데 CS10 때 JK가 언급했던 내용인데 그 때 완벽히 이해하지 못해서 복습차 들었습니다.

Integer overflow

int 자료형(4 byte)은 최대 32 bit(8 bit * 4)로 숫자를 표현할 수 있다. 일반적으로 java에서 사용하는 signed int 기준으로 보면, 2^32개의 숫자를 양수/음수로 나누어 -2^32~-1 / 0~2^32-1 로 표현할 수 있다. 한 마디로 -2^32~2^32-1까지 표현할 수 있다. 그런데 이 표현 가능한 숫자를 넘어 저장하려고 하면 이상한 일이 벌어지기 시작한다.

편의상 1바이트 자료형을 예로 들자. 2^7-1이 저장되어 있는 1바이트 자료형을 이진수로 표현하면, 01111111일 것이다.

여기다 1을 더하면 어떻게 될까? 당연하게도 10000000이 된다. 컴퓨터는 시키는 대로 수학적으로 올바른 계산을 했지만, 자료형 표현 체계상 10000000 = -128이므로 원하는 결과와 다른 결과가 나오는 것이다.

그래서 java에서는 int(4 byte), long(8 byte)를 기억하여 적절한 크기의 자료형을 쓸 수 있도록 유념해야 한다.

(여담으로 c++의 long은 4 byte(32 bit OS 기준), char는 1 byte(자바는 인코딩 방식이 유니코드라서 2 byte라고 한다)로 java와 조금씩 다르다.. 헷갈린다)

실수 자료형

정수가 아닌 실수는 어떻게 이진수로 나타낼까? 간단하게도, 2^-1, 2^-2 등을 활용하면 된다. 물론 이렇게 표현하면, 당연히 오차가 발생한다.

float, double 등은 각각 4 byte, 8 byte의 크기를 가진다.

정수와 마찬가지로 맨 앞 bit는 양수/음수를 나타내고, 뒤로는 서로 다른 크기의 exponent, fraction field를 가진다.

유효숫자 표기법처럼, 유효숫자를 fraction에, 지수부분을 exponent에 저장하는 식이다. -6.75 = -1.1011(2) x 2^2로 표현가능하다.

당연하게도, double의 fraction field 크기가 더 클것이고 그만큼 정밀도가 올라갈 것이다. 십진수로 생각할 때 float은 유효숫자 7자리, double은 15자리의 정밀도를 가진다고 한다.

💪 좋은 점

  • 조금씩 내가 작성하고 적용하는 것들의 의미를 찾아 나가고 있다.
  • 좀 깊게 공부하는 습관을 들여가고 있다.

👀 아쉬운 점

  • 개인 일정 때문에 공부량이 부족했다 ..ㅠㅠ

🗒 개선 방향

  • 약속을 조금 줄여보고 평소에 많이 공부하자!
profile
천천히, 하지만 꾸준히 그리고 열심히

0개의 댓글