최근에 CMC라는 동아리를 하면서 새로운 프로젝트를 진행하고 있습니다.

 

이 과정에서 삽질 때문에 시간을 너무 많이 써서.... 해당 내용을 기록해두려고 합니다.

 

원래는 GKE를 이용해서 배포를 하려 했었는데, 계속 서비스가 정상적으로 동작하지 않아서 vm instance를 이용해서 배포는 해둔 상태입니다.

 

 

 

1. 문제

우선 서버 세팅은 vpc 를 통해서 priavte subnet(10.0.1.0/24)이랑 public subnet(10.0.2.0/24)을 만들었습니다.

그리고 cloud sql을 private subnet에 등록하려고 했지만, 

이처럼 비공개 서비스 액세스라는 것을 만들라고 해서 이를 이용해서 만들었습니다.

이는 10.0.3.0/24 범위를 가지고 있습니다.

 

여기서 문제가 10.0.3.0/24의 db와 10.0.2.0/24의 vm 인스턴스가 서로 통신이 안되는 상황이었습니다.

 

 

2. 해결

저는 당연히 subnet끼리는 통신이 원활히 될 줄 알았습니다. 하지만 그렇지 않았습니다.

서로 방화벽을 뚫어줘야지 통신이 가능해집니다....

 

그래서 vpc의 방화벽에서 

vpc 방화벽 추가

 

이러한 조건을 추가해줬습니다. 그러니 db랑 연결이 잘 됩니다.

 

 

 

이 간단한 것을 못 찾아서 거의 2시간 쓴 것 같았습니다... 이상한 곳에 문제가 있다고 생각하고 계속 다른 데를 봤네요.

회사에서는 인프라팀이 이러한 일을 다 해주고 있어서 신경을 쓸 필요가 없었습니다. 사실 vpc 설정하고 서버를 배포해보는 것도 이번이 처음이네요. 이 기회로 제가 많이 부족하다는 것을 느낄 수 있었습니다.

반응형

평소 TDD나 클래스 설계에 관심이 있었습니다.

 

그래서 책을 통해 공부는 했지만, 이 지식을 이용해 구현한 코드가 제대로 된 구조인지 궁금해서 이 프로그램에 참여했습니다.

(현재 회사에서는 코드 리뷰 문화가 없습니다 ㅎㅎ..)

 

 

 

과제가 총 4개 있고, 이를 구현하고 PR을 보내면 리뷰를 받는 방식으로 진행이 되고 있습니다.

리뷰는 현업자 분들에게 받기도 하고 해당 프로그램이 가격대가 나가는 편이라서 꼼꼼하게 리뷰 해주십니다.

 

 

 

인상깊었던 점은 캐시 관련해서 인상깊었습니다.

내용이 인상깊었다기 보다는 제 공부 태도에 대해 반성을 할 수 있었습니다.

 

자주 이용하는 클래스는 계속 새로 만들기 보다는 캐싱을 해서 이용하면 heap 공간을 절약할 수 있습니다.

Java의 Integer에 캐싱을 이용하는 것은 알고 있었습니다. 하지만 이를 응용할 생각은 전혀 못하고 있었습니다.

공부할 때 그렇구나하고 끝내는 게 아니라 어떻게 응용할 것인지까지 고민을 해봐야 겠습니다.

 

 

 

하지만 주변에 추천은 하지 않을 것 같습니다..

물론 리뷰도 잘 해주고 좋지만, 이 과정이 80만원이나 할 이유는 없다고 생각을 합니다.

돈에 여유가 있다면 괜찮지만, 저 같은 사회 초년생에게는 추천을 안할 것 같네요.

 

 

 

그래도 이 과정 덕분에 3~4월 동안 공부 열심히 했네요.

반응형

안녕하세요. 3주 차는 건너뛰고 바로 4주 차로 왔습니다.

 

3주 차를 회고하지 않은 이유는 이전에 회고했던 내용이랑 크게 다르지 않았습니다.

 

4주 차는 생각보다 많이 어려웠습니다.

기능이 복잡하기보다는, 클래스 설계하고 테스트하기가 어려웠습니다.

 

과제 내용

간단하게 요약해서 설명드리겠습니다.

 

https://github.com/Danden1/java-christmas-6-Danden1

 

GitHub - Danden1/java-christmas-6-Danden1

Contribute to Danden1/java-christmas-6-Danden1 development by creating an account on GitHub.

github.com

자세한 문제 내용은 이를 참고해 주시면 되겠습니다.

 

12월에 메뉴를 시키면, 이를 할인해 주고 얼마만큼 할인되는지를 출력해 주는 과제입니다.

하지만 할인 전략이 매우 많습니다. 특별한 날(식당 지정)에 할인을 해주거나, 어떤 카테고리의 메뉴를 주말/평일 별로 할인을 다르게 해주는 등 전략이 매우 다양했습니다.

 

그리고 증정품을 주는 이벤트도 있는데, 증정품의 가격도 할인 가격으로 포함해서 출력을 해야 합니다.

(예를 들면, 샴페인을 증정했으면 샴페인의 가격만큼 할인되었다고 판단합니다.)

 

저는 이를 어떻게 설계할 지 고민이 많이 되었습니다.

 

클래스 설계

 

Menu 

우선 메뉴 카테고리 별로 메뉴판을 만들었습니다.

 

 

이런 식으로 구현했습니다. 

 

이렇게 하면 카테고리 별로 쉽게 관리할 수 있을 것이라고 생각했습니다.

그리고 MenuFinder는 메뉴 이름을 통해서 어떠한 메뉴의 무슨 음식인지 찾아줍니다.

 

Discounter

앞에서 설명드렸다시피, 할인 전략이 매우 다양합니다. 저는 그래서 이를 나눴습니다.

OrderRequestDto에는 메뉴 주문 시간과 메뉴 리스트들이 있습니다.

응답으로는 이렇게 할인 금액과 할인 이벤트 이름에 대한 정보를 가지고 있습니다.

 

이를 이용해서 이렇게 구현할 수 있습니다.

 

 

여기서 문제는 증정 할인이였습니다.

증정품의 가격도 할인으로 포함시키는 것이 문제였습니다.

 

 

그래서 ReseponseDto를 확장시켰습니다.

이런 식으로 했습니다. 만약 증정품이 없다면, 할인 금액이 0원인 것으로 했습니다. 이는 Optional을 활용했습니다.

 

그리고 이를 반환하도록 했습니다.

 

 

Order

주문에 관한 클래스입니다.

 

이런 식으로 구현했습니다. Discounter 목록들을 받고, 이를 활용해서 계산을 하게 됩니다.

만약 새로운 할인 전략이 추가되거나 제거되더라도 Order는 이에 관해 크게 상관이 없습니다.

이는 단위 테스트하기도 쉬워집니다.

 

 

이런 식으로 임의의 할인 전략을 만들고 이를 활용하면 됩니다.

 

이를 이용하여 Order 클래스를 테스트할 수 있습니다.

 

 

User

유저가 주문하면, 할인받은 금액에 따라서 배지를 설정해줘야 하는 기능도 있습니다.

이에 관한 클래스입니다.

 

이 부분도 앞의 Order처럼 테스트하기 쉽도록 DI를 이용했습니다.

이렇게 간단하게 할 수 있습니다.

 

즉, Order와 유저가 서로 분리되어 있습니다.

 

느낀 점

이번 과제를 하면서 많이 리팩터링을 했습니다. 테스트 코드를 구현하기 위해서 고치고 고치고 고치고... 를 반복했던 것 같습니다.

 

문제는 이렇게 하다 보니 시간이 부족했습니다. 제가 평일에는 직장을 다니다 보니, 시간이 많이 부족했습니다. 테스트 코드가 확실히 시간을 많이 잡아먹는다고 느꼈습니다. 장점이 있는 만큼 단점도 있는 법이죠.

경험이 많이 쌓이면 개발 속도는 빨라질 것이라고 믿습니다. 

(이를 위해 개발 동아리를 지원해보고 있는데, 쉽지 않네요...)

 

그리고 요구사항을 제대로 문서로 정리하지 않아서 몇몇 기능(메뉴 20개 이상 주문 불가, 10,000원 이하 주문 불가 등)이 빠졌습니다. 문서화를 꼼꼼하게 해야 될 필요성을 느꼈습니다.

귀찮다고 대충 하면 개발 단계에서 피보네요.

 

개발은 진짜 꼼꼼함이 중요한 것 같습니다.

 

 

 

전체적으로 작년보다 실력이 많이 늘어서 기분이 좋네요.

5기 때, 저랑 같이 참여하던 친구가 있습니다. 이 친구랑 5기 때도 서로 코드리뷰를 했었는데, 이번에도 진행했습니다.

실력이 많이 늘었다고 친구도 놀라워했습니다. 

 

앞으로 더 노력하는 개발자가 되어야겠네요.

반응형

작년에 참가했었지만, 2주 차는 다른 문제였습니다.

 

https://github.com/Danden1/java-racingcar-6/tree/Danden1

 

GitHub - Danden1/java-racingcar-6

Contribute to Danden1/java-racingcar-6 development by creating an account on GitHub.

github.com

 

이번에는 테스트 코드 작성을 위해 리팩토링을 많이 진행했었습니다.

 

이번 조건으로는 랜덤으로 9까지 숫자를 생성하는데, 4 이상 일 경우만 전진을 진행하도록 해야 했습니다.

이 랜덤 값을 테스트하기 위해서 리팩토링을 진행했습니다.

 

처음 코드입니다.

처음에 짠 코드가 저 빨간 줄 입니다. 이는 테스트할 방법이 없습니다.

그래서 추가한 것이 초록색 줄입니다. MoveCommandMaker를 통해 테스트하도록 했습니다.

이렇게 테스트를 했습니다.

하지만 이는 4 이상일 경우 전진하는 지 테스트를 하지 못합니다.

 

그래서 리팩터링을 진행했습니다.

리팩터링한 후의 코드입니다.

요구사항을 테스트할 수 있도록 바꿨습니다.

 

테스트 코드에 대해서도 공부를 해볼 필요가 있네요. 공부할 것이 너무 많네요.

반응형

작년에도 프리코스에 참가를 했었습니다.

 

작년과 비교하여 얼마나 발전했는지 궁금해서 이번에 참여해 봤습니다.

 

작년 코드

 

우선 작년에 구현했던 코드 구조부터 한 번 보겠습니다.

https://github.com/Danden1/java-baseball/tree/Danden1

 

GitHub - Danden1/java-baseball: 숫자 야구 게임 미션을 진행하는 저장소

숫자 야구 게임 미션을 진행하는 저장소. Contribute to Danden1/java-baseball development by creating an account on GitHub.

github.com

 

이렇게 분리했었네요.

 

Model에 숫자를 만들고, 유효성을 검사하고 strike가 몇 개인지 판단하는 등 모든 기능이 들어가 있습니다. 이는 확장성에 별로죠.(SRP 위반) 지금 보니까 진짜 대단하네요....

 

이후에 인턴을 하고 공부를 하면서 엄청나게 발전한 것이 느껴집니다.

 

 

 

어떤 점이 발전했을까요?

 

현재 코드

 

그럼 이번에 작성한 코드 구조입니다.

https://github.com/Danden1/java-baseball-6/tree/Danden1

 

GitHub - Danden1/java-baseball-6: 2번 째 참여

2번 째 참여. Contribute to Danden1/java-baseball-6 development by creating an account on GitHub.

github.com

이런 식으로 설계를 했습니다.

 

domain layer

그리고 domain layer부터 한 번 보겠습니다.

저는 도메인을 이렇게 분석했습니다. 숫자야구 결과를 반환해 주는 심판이 있고, 숫자를 생성해 주는 인터페이스가 있습니다. 그리고 숫자 야구 결과에 대한 클래스도 있습니다. 

 

그리고 BaseballNumber를 만들기 위해 의존성 주입을 이용했습니다.

이렇게 함으로써 유연한 코드를 작성할 수 있습니다.

아래는 이를 이용하여 작성한 테스트 코드입니다.

게임 결과를 테스트하는 코드입니다. 의존성 주입을 사용함으로써 단위 테스트가 가능하게 됩니다. 어떻게 숫자를 만드는지는 크게 관심이 없습니다. 그래서 임의로 123을 반환하는 클래스를 만듦으로써 테스트를 쉽게 할 수 있습니다.

 

infra layer

 

infra layer에는 BaseballNumberGenerator 인터페이스를 구현한 구현체가 있습니다.

왜 이를 infra라고 생각을 했냐면, 컴퓨터의 숫자는 랜덤으로 생성할 수도 있고 특정한 패턴을 가지고 생성할 수도 있다고 생각하여 확장성을 고려해서 설계했습니다. 이 부분은 기술적인 부분이라고 생각합니다. 

Type은 Enum으로 USER, COMPUTER 가 있습니다. 나중에 factory를 이용하여 타입에 맞는 해당 객체를 반환하게 됩니다.

이렇게 해당 타입에 맞는 BaseballNumberGenerator를 반환하게 됩니다. 나중에 난이도에 따라서 computer가 생성하는 숫자가 달라진다면, 여기다가 타입(난이도)만 더 추가해 주면 됩니다. 이는 확장을 하기 쉬워집니다.

그리고 싱글톤을 이용함으로써 객체가 생성되는 데에 드는 오버헤드가 줄어듭니다.

 

Computer에 해당하는 테스트 코드입니다.

아쉬운 점은 Baseball의 BASBALL_NUMBER_LEN에 의존적인 부분입니다. 만약 baseball의 len을 변경하게 되면 이는 실패하게 됩니다. 왜냐하면 baseball.size()가 3이라고 이미 가정을 했기 때문입니다. 이 부분이 많이 아쉽네요.

 

사실 BaseballNumberGenerator의 기능만 테스트한다기보다는 실제로 숫자야구가 만들어지는 동작을 테스트하는 경우입니다. 

좋은 코드, 나쁜 코드 책에서는 실제 기능(함수)만 테스트하기보다는 동작을 테스트하라고 합니다. 이는 여러 가지 함수를 거쳐서 실행될 수 있다고 합니다. 이를 고려하면 괜찮다는 생각이 들기도 하네요.

appl layer

이렇게 factory를 이용하여 baseballNumberGenerator를 받아서 숫자를 생성하게 됩니다.

 

presentation layer

service를 이용하여 게임을 실행하게 됩니다.

 

후기

1년 사이에 엄청나게 발전한 것 같습니다. 하지만 아직 부족한 점이 많이 느껴지네요. 너무 기능을 쪼개고 확장성에 초점을 둔 것 같기도 하다는 생각이 듭니다. 그리고 DDD를 이용하고 싶은데 실제로 이렇게 이용하는 것이 맞는지 궁금하네요.

 

DDD에 대해서 공부할 필요성이 있다고 느껴서, 도메인 주도 설계 첫걸음 이라는 책을 사서 현재 공부해보고 있습니다.

 

 

 

다른 분들에게 리뷰를 받아보고 싶어서 글을 올렸었는데, 슬프게도 리뷰해 주시는 분이 안 계시네요.

 

제가 먼저 접근을 해봐야겠습니다.

 

 

좀 더 노력을 해서 1인분 넘게하는 개발자가 되고 싶네요.

반응형

이번에 일을 하면서 개발 환경 구축을 하게 되었습니다.

 

보통 대부분의 프로젝트가 db를 이용할 것 입니다.

하지만 로컬에서 테스트를 해보기 위해 stage나 live 서버의 데이터를 조작하면 그 db로 테스트하고 있던 사람은 불편하겠죠.

 

그렇다고 새로운 프로젝트에 인원이 투입될 때마다, 로컬에 맞는 db를 만들면 시간이 매우 낭비됩니다.

 

이를 해결하기 위해서 DB 세팅(table, user, function, index 등)을 db에 올리고 테스트할 수 있도록 합니다.

 

보통 docker-compose를 이용하여 합니다.

version: '3.1'

services:
	db:
    	images:mysql
        ...
        ...
        volumes: ./test /docker-entrypoint-initdb.d/
        ...

하지만 db 관련 정보는 volume을 이용하기 때문에 이 컨테이너를 commit 해도 db 세팅했던 것들은 유지되지 않습니다.

 

물론 로컬에 마운트를 하면 백업 본이 생기지만, 다른 곳에서는 이미지를 가져와서 실행하면 백업 본도 못 봅니다.

 

 

이를 해결하기 위해서 직접 Dockerfile을 수정했습니다.

이는 github에서 손쉽게 구할 수 있습니다.

 

Dockerfile을 보면,

volume이 설정되어 있는데, 이를 지워주면 됩니다. 

그리고 아래를 보면 COPY ... 이 있는데 이 파일도 가져와야 합니다(git에 Dockerfile이랑 같이 있습니다).

 

ENV POSTGRES_USER <user name>

ENV POSTGRES_PASSWORD <password>

COPY <sql path> /docker-entrypoint-initdb.d/

그리고 이렇게 더 넣어줘야 합니다.

만약 db 세팅이 필요가 없다면 COPY 부분은 안 넣어도 됩니다.

 

아니면, /bin/bash에 들어가서 직접 table을 만드는 등 세팅을 해주시고

docker commit을 하면 됩니다.

 

 

이렇게 하면 이미지를 배포할 경우 다른 사용자들이 db를 그대로 활용할 수 있습니다.

데이터(row)도 유지할 수 있습니다.

 

 

 

이상하게도 저는 

이 부분에서 계속 general error가 발생했다고 합니다. 

 

링크를

keyserver.ubuntu.com

로 수정하니까 잘 되었습니다.

 

저도 그 이유는 잘 모르겠네요. 여기서 삽질을 엄청한 것 같습니다.

 

반응형

+ Recent posts