진행중인 프로젝트에 Jira를 처음 사용해봤는데 맛만 봤는데도 너무 편리하고 유용한 것 같다. 지라로 이슈를 생성하면 티켓 번호가 할당되는데 해당 티켓 번호로 브랜치를 만들고 커밋 메시지에 티켓 번호를 입력하면 해당 이슈에서 편리하게 볼 수 있다.

 

깃허브에도 이슈가 있긴하지만 잠깐 사용해본 느낌으로는 지라가 깔끔하고 눈에 확 들어와서 좋은 것 같다. 하지만 깃허브 이슈와 마찬가지로 티켓 번호를 입력하는 것을 실수로 깜빡하거나 틀리게 적는 경우가 종종 생길 수 있는데 좋은 방법이 없나 찾아보니 git hook을 사용해서 티켓번호 입력을 자동화 해줄 수 있었다.

 

 

 

 

훅으로 Git에 훅 들어가기 | 우아한형제들 기술블로그

{{item.name}} 들어가며… 안녕하세요. 우아한형제들 CTO실 주문시스템개발팀의 라태웅입니다. 요새 Git은 어느 조직이건 개인이건 많이 사용하고 계신데요, 굉장히 많은 기능이 있죠. 이중 몰라도

techblog.woowahan.com

 

git hook은 git에서 특정 상황에 특정 스크립트를 실행하는 기능으로 git repository에서 기본으로 지원을 하고 있다. 깃 훅을 잘 활용하면 잘못 푸쉬하는 것을 사전에 막는 등 유용한 기능이 많은 것 같다. 이번에 사용할 것은 prepare-commit-msg으로 커밋 메시지를 만든 후에 실행이 되는 훅이다. 아래 블로그를 보고 prepare-commit-msg.sample 파일을 수정해서 커밋을 할 때 브랜치 이름으로 이슈 번호를 찾아서 커밋 메시지 앞에 추가를 하도록 변경을 했다.

 

 

GitHub 커밋 메세지에 JIRA 이슈번호 자동으로 넣어주기

항상 앞에 이슈번호를 넣어주어야 하는 귀찮음을 자동으로 넣어주도록 처리하는 방법에 대해 공유합니다.

medium.com

 

근데 스크립트는 실행이 되는데 뭐가 잘못된건지 계속 적용이 안되서 삽질하다가 결국 아래 방법으로 해결을 했다..(ㅠㅠ)

 

git hook은 .git 디렉토리에 저장되기 때문에 설정 스크립트나 템플릿을 활용하는 등의 방법으로 공유를 해야 되는데 이런 방법은 실수를 하면 제대로 적용이 안 될 수도 있다고 한다. 그래서 npm을 사용하고 있다면 husky 사용을 권장하는데 husky는 npm 모듈로 편리하게 깃 훅을 적용할 수 있다. husky로 지라 티켓번호 자동화를 하는 방법은 아래 블로그에 깔끔하게 나와있다.

 

 

[Husky] 커밋메시지 JIRA 티켓번호 자동화

Husky husky는 .git/hooks 폴더를 건드리지 않고도 git hook 스크립트를 제어할 수 있게 해주는 툴입니다. 설정과정 1. Husky 설치 npm install husky jira-prepare-commit-msg --save-dev && npx husky install 2. 훅 생성 npx husky

waterfogsw.tistory.com

 

가비아 라이브러리

IT 콘텐츠 허브

library.gabia.com

 

 

프로젝트를 하면서 fetch join을 다시 JPA 책을 보면서 복습했다.

 

fetch join은 JPQL 기능으로 연관된 엔티티나 컬렉션을 한번에 같이 조회하는 것이다.

 

"select m from Member m join fetch m.team"

 

이렇게 페치 조인을 하면 Member만 조회를 했지만 실제 쿼리는 Member와 연관된 Team도 함께 조회하게 된다.

페치 조인을 사용하지 않을 경우 Member만 조회하고 조인을 한 Team은 조회하지 않는다.

연관 관계가 지연 로딩으로 설정 되어 있으면 프록시나 아직 초기화 되지 않은 컬렉션 래퍼를 반환한다. 그리고 나중에 접근할때 추가로 쿼리가 나가기 때문에 페치 조인을 잘 활용하는 것이 좋다.

 

fetch join을 사용할때 주의할 점

 

1. 페치 조인 대상에 별칭을 잘못 사용하면 연관된 데이터 수가 달라져서 데이터 무결성이 깨질 수 있으므로 조심해서 사용해야 한다. (연관된 데이터 수가 달라진 상태에서 2차 캐시에 저장되면 위험)

 

2. 둘 이상의 컬렉션을 페치할 수 없다. (카테시안 곱) -> @BatchSize 활용

 

3. 컬렉션을 페치 조인하면 페이징 API를 사용할 수 없다. (경고 로그를 남기면서 메모리에서 페이징 처리를 해서 위험)

 

도메인 패턴을 중심에 놓고 설계하는 DDD(Domain-Driven Design)도메인별로 분리를 시켜

높은 응집력과 낮은 결합도로 변경과 확장에 용이한 설계를 할 수 있도록 한다.

 

일반적으로 Layered Architecture는 Presentation -> Application -> Domain -> Infa 의 구조를 가진다.

 

Presentation

- 표현 계층 (Controller)

- 사용자의 요청을 해석하고 응답

- Client로부터 request를 받고 response를 반환하는 API 정의

 

Application

- 응용 계층 (Service)

- 비즈니스 로직을 정의하고 정상적으로 수행될 수 있도록 Domain 계층과 Infra 계층을 연결해주는 역할

- 많은 정보를 가지고 있지 않게 유지하는 것이 중요

- 실질적인 데이터 처리는 Domain 계층에 위임

- 트랜잭션의 단위, Entity 조회/ 저장

 

Domain

- 도메인 계층 (Model)

- 비즈니스에 대한 실질적인 Domain에 대한 정보를 가지고 책임지는 계층

- Entity를 활용하여 상태를 제어하는 역할에 집중

 

도메인 객체에 비즈니스 로직을 구현하면 객체지향적인 설계(객체에 요청)와 도메인 객체의 응집도를 높일 수 있다. 도메인 객체만 봐도 이 객체가 어떤 상태를 가지고 어떤 동작을 하는지 파악할 수 있다. 그리고 서비스 계층의 코드가 간결해져서 비즈니스 로직의 흐름이 자연스러워진다.

 

Infastructure

- 인프라 계층 (Repository)

- 외부와의 통신(DB)을 담당하는 계층

- 얻어온 정보를 Application 또는 Domain 계층에 전달하는 역할

 

Repository는 Domain을 영속화하는데 필요한 일종의 명세로 도메인 관점에서 정의를 하고 실제 구현에 대한 부분은 Infa로 분리시킨다.

DIP(고수준 모듈이 저수준 모듈에 의존하지 않도록 하기 위함)를 이용해서 도메인 계층에 Repository 추상화를 만들고 실제 구현은 Infra 계층에서 하는 것이다.

 

아직 DDD를 잘 이해하고 있진 않은데 한번 개인 프로젝트에 써보면서 공부해봐야겠다.

 

 

 

[DDD] Repository Pattern 이란, 이론편

이 글은 이론과 실습, 두 파트로 나뉘어져 있습니다. Repository Pattern 에 대해서, 이론편

wonit.tistory.com

 

인터페이스와 구현체의 패키지 관련 질문입니다 - 인프런 | 질문 & 답변

안녕하세요. 영한님. 복슴겸 해서 강의를 다시보다 궁금한 점이 있어 질문드립니다. 강의에서 member 패키지에 MemoryRepository 인터페이스를 작성하셨고 해당 인터페이스의 구현체는 다른 패키지에

www.inflearn.com

 

[Spring] 도메인 주도 설계 및 개발과 도메인 계층(도메인 객체 중심 개발)

이 내용은 토비의 스프링 1권의 797부터 시작하는 내용을 참고하며 작성하였습니다. 1. 도메인 주도 설계 및 개발(도메인 객체 중심 개발) [ 도메인 객체 중심 개발 ] 도메인 객체 중심 아키텍처란

mangkyu.tistory.com

 

 

DDD(Domain-Driven Design) 계층구조(Layered Architecture) 알아보기

시작하기 앞서 도메인이 무엇인지, 도메인 주도 설계(Domain-Driven Design)란 무엇인지부터 가볍게 알고 넘어가자. 도메인이란 사전적 의미는 '영역', '집합'이다. '실세계에서 사건이 발생하는 집합'

dev-coco.tistory.com

 

 

컴퓨터의 개수(n)와 컴퓨터간 네트워크 연결 정보(computers)가 주어졌을때 네트워크의 개수를 구하는 문제로 아래의 경우 A와 B가 연결 되어 있고, C는 따로 있으므로 총 네트워크 수는 2개가 된다.

  A B C
A 1 1 0
B 1 1 0
C 0 0 1

 

예전에 푼 문제를 다시 보니 전에는 문제를 어떤식으로 풀까 하는 생각을 별로 안하고 풀었던 것 같다.

 

class Solution {
    static int L;
    static boolean flag = false;
    static int[][] ch;

    public int solution(int n, int[][] computers) {
        ch = new int[n][n];
        L = 1;
        for (int i = 0; i < n; i++) {
            flag = false;
            BFS(i, n, computers);
            if (flag)
                L++;
        }
        return L - 1;
    }

    private static void BFS(int i, int n, int[][] computers) {
        Queue<Integer> queue = new LinkedList<>();
        queue.offer(i);
        while (!queue.isEmpty()) {
            int p = queue.poll();
            for (int j = 0; j < n; j++) {
                if (computers[p][j] == 1 && ch[p][j] == 0) {
                    flag = true;
                    ch[p][j] = L;
                    ch[j][p] = L;
                    queue.offer(j);
                }
            }
        }
    }

}

 

다시 푼 코드인데 0 ~ n-1개 컴퓨터를 돌면서 network[] 체크가 안되어있으면 새로운 네트워크로 보고 count를 증가시킨다.

dfs는 해당 컴퓨터에 연결된 다른 컴퓨터를 체크하면서 network[]를 true로 바꾼다.

 

class Solution {
    static boolean[] network;
    static int[][] computers;
    
    public int solution(int n, int[][] computer) {
        computers = computer;
        network = new boolean[n];
        int count = 0;
        
        for (int i = 0; i < n; i++) {
            if (!network[i]) {
                count++;
            }
            dfs(n, i);
        }
        
        return count;
    }
    
    private void dfs(int n, int i) {
        network[i] = true;
        
        for (int j = 0; j < n; j++) {
            if (!network[j] && computers[i][j] == 1) {
                dfs(n, j);
            }
        }
    }
}

 

 

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

+ Recent posts