각종 후기/우아한테크코스

[우아한 테크코스 3기] LEVEL 1 회고 (59일차)

제이온 (Jayon) 2021. 4. 1.

안녕하세요? 제이온입니다.

 

오늘은 LEVEL 1 마지막 날입니다. 크루들과 함께 힘내서 체스 미션을 진행했습니다.

 

 

데일리 미팅

오늘은 워니가 오랜만에 데일리 미팅을 진행해 주셨습니다. LEVEL 1 동안 하겠다고 한 목표를 각 크루들이 수행했는지 확인하는 시간을 가졌고, 2/3 정도의 인원이 성공한 것 같았습니다. 저는 주말과 공휴일을 제외한 날에 대해 1일 1회고를 블로그에 작성하겠다고 했고, 다행히 하루도 빠짐 없이 포스팅을 했습니다.

 

이후에는 다들 자리에서 일어나기가 싫어가지고 로키가 라이어 게임을 진행해 주었습니다. 다들 짧은 시간동안 게임을 하면서 체스 미션을 진행할 수 있는 원동력을 얻었다고 생각합니다.

 

 

체스 미션 리팩토링

어제 말한 코드가 길었던 부분은 메소드 분리를 통해 해결하였습니다. 그리고 캐싱과 관련된 부분은 그대로 두되, DAO가 아닌 PieceFactory 클래스로 로직을 위임하였습니다.

 

 

public class PieceFactory {

    private static final Map<String, Piece> PIECES = new HashMap<>();

    static {
        PIECES.put("p", new Pawn(Team.WHITE));
        PIECES.put("P", new Pawn(Team.BLACK));
        PIECES.put("q", new Queen(Team.WHITE));
        PIECES.put("Q", new Queen(Team.BLACK));
        PIECES.put("r", new Rook(Team.WHITE));
        PIECES.put("R", new Rook(Team.BLACK));
        PIECES.put("b", new Bishop(Team.WHITE));
        PIECES.put("B", new Bishop(Team.BLACK));
        PIECES.put("k", new King(Team.WHITE));
        PIECES.put("K", new King(Team.BLACK));
        PIECES.put("n", new Knight(Team.WHITE));
        PIECES.put("N", new Knight(Team.BLACK));
        PIECES.put(".", Blank.getInstance());
    }

    public static Piece correctPiece(final String name) {
        return PIECES.get(name);
    }

}

 

 

그래서 DAO의 책임은 줄었지만, 그래도 뭔가 불-편한 느낌이 듭니다. 이 부분은 리뷰어 님께 질문해 보기로 했습니다.

 

 

다음으로, try~with~resource를 적용해 보았습니다. DB에서 쿼리문을 보내기 전에 매번 연결을 하고, 해당 메소드를 종료하기 전에 연결을 끊어야 합니다. 이때, 예상치 못하게 에러가 나는 부분에 대해서도 연결을 끊는 메소드를 추가해 주어야 해서 번거롭다는 단점이 있습니다. 이를 해결하기 위한 방법이 바로 try~with~resource입니다.

 

 

    public void savePiece(final Position position, final Piece piece) throws SQLException {
        try (final Connection conn = ConnectionSetup.getConnection()) {
            final String query = "INSERT INTO pieces VALUES (?, ?)";
            final PreparedStatement pstmt = conn.prepareStatement(query);
            pstmt.setString(1, position.horizontalSymbol() + position.verticalSymbol());
            pstmt.setString(2, piece.name());
            pstmt.executeUpdate();
        }
    }

 

 

위와 같이 try 안에서 Connection 객체를 할당해 주면, try문이 끝날시 알아서 연결이 해제됩니다. Connection 이외에도 여러 가지 객체에 대하여 자원 해제를 편하게 할 수 있으므로 잘 숙지해 두어야겠습니다.

 

 

세 번째는 이동할 때마다 테이블의 데이터를 싹 지우고, 64개의 데이터를 테이블에 새롭게 넣는 것이 아니라, 2개의 데이터만 추가하도록 수정했습니다.

 

 

    public void savePiece(final Position position, final Piece piece) throws SQLException {
        try (final Connection conn = ConnectionSetup.getConnection()) {
            final String query = "INSERT INTO pieces VALUES (?, ?)";
            final PreparedStatement pstmt = conn.prepareStatement(query);
            pstmt.setString(1, position.horizontalSymbol() + position.verticalSymbol());
            pstmt.setString(2, piece.name());
            pstmt.executeUpdate();
        }
    }

 

 

위 메소드를 source, target에서 각각 1번씩만 실행해서 데이터를 추가해 주었습니다. 해당 메소드의 문제점은 동일한 위치에 다른 체스말이 들어갈 수 있다는 것입니다. 하지만, 어차피 하나의 게임만 진행하고 있고 Map으로 체스판을 만들었으므로 데이터베이스의 가장 마지막 value가 들어가서 로직 상의 문제는 없었습니다. 다만, 이 부분은 Primary Key 등을 공부해서 중복 제거를 해 보아야겠습니다.

 

 

마지막으로는 테이블의 모든 데이터를 지울 때는 DELETE 대신 TRUNCATE를 사용하자는 것입니다. 이것은 바다가 알려주었는데, DELETE를 통해 테이블의 모든 데이터를 지우면 한 줄 한 줄씩 지우다보니까 딜레이가 생겨서 게임 플레이에 문제가 생길 수 있다는 것입니다. 그래서 한 번에 지워주는 TRUNCATE 쿼리문을 작성해야한다고 알려주었습니다. 덕분에 가끔씩 에러가 나는 이유를 찾아낼 수 있었습니다.

 

 

    public void deleteAll() throws SQLException {
        try (final Connection conn = ConnectionSetup.getConnection()) {
            final String query = "TRUNCATE TABLE pieces";
            PreparedStatement pstmt = conn.prepareStatement(query);
            pstmt.executeUpdate();
        }
    }

 

 

정리

비록 선택 요구 사항은 구현하지 못했지만, 필수 요구 사항이라도 구현해서 오늘 PR을 날린 것에 만족합니다. 방학 때의 원래 스프링을 예습하려고 하였으나, DB의 개념이 워낙 없어서 'SQL 첫걸음' 책을 읽을 생각입니다. 그 외에는 휴식을 1순위로 두면서 체스 리뷰 및 DB 공부를 하면 될 것 같습니다.

 

오늘은 LEVEL 1이 끝났고, 때마침 아론이 이사를 했다길래 집들이를 가기로 했습니다. 그동안 고생했으므로 오랜만에 술을 좀 먹으려고 합니다 ㅎㅎ

댓글

추천 글