Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[노을] 미션 4: 모든 기물 배치하기 #150

Merged

Conversation

sanhee
Copy link

@sanhee sanhee commented Feb 24, 2021

안녕하세요😃 코드스쿼드 백엔드 과정 노을입니다.

이번 미션은 자바 기초 공부를 하느라 늦게 진행 하게 되었습니다.

기초 공부를 하면서 자바의 상속과 그리고 요구사항에서 학습하게 된 정적 팩토리 메서드를 학습 차원에서 사용 해보고 싶어,

요구사항과는 다르게 Piece 클래스를 체스 유닛들의 조상 클래스로 만들어 하위 유닛들이 상속을 받는 구조로 설계하였습니다.

혹시 이와 같이 하면 안되는 것이라 하면 요구사항에 맞게 다시 PR 요청을 드리도록 하겠습니다.😂

클래스 구성

궁금한 점은 정적 팩토리 메서드를 아래와 같이 구현을 했는데 올바르게 활용 했는지 잘 모르겠습니다.

public class PieceFactory {
    public static Piece createBishop(UnitColor unitColor) { //m 정적 팩토리 메서드
        return new Bishop(unitColor);
    }

    public static Piece createKing(UnitColor unitColor) {
        return new King(unitColor);
    } 
    ... 반복

마지막으로 요구사항과는 관련없는 이야기이지만 문득 체스 게임이라고 생각하니까 좌표정보에 대한 책임을 Board 클래스에게 줄 것인지, 체스 유닛들이 개별적으로 가지고 있게 할 것 인지 고민을 하게 되었는데, 어떻게 하는게 좋은 방식인지 궁금합니다.

오늘도 바쁜 시간 내어 리뷰해주셔서 감사합니다.😎

 - 요구사항과 같이 기존 \n을 운영체제 독립적으로 만들기 위해
 - utils.StringUtils 클래스를 추가하였고,
 - System.getProperty("line.separator")룰 이용하였습니다.
- 요구사항을 반영하기 위해 클래스 이름을 변경하였습니다.
- 요구사항을 반영하기 위해 클래스 이름을 변경하였습니다.
- 기물 클래스 이름을 받아와 해당하는 상수에 대한 기호를 찾습니다.
- 색상에 따라 대소문자를 설정하여 리턴합니다.
- Piece를 Pawn, King등 기물들의 조상 클래스로 지정하기 위해 추상클래스로 정의하였습니다.
- 생성자 함수에서 기물의 클래스이름과 색상을 매게변수로 UnitType 열거형에서 기물의 기호를 가져옵니다.
- 체스에 사용되는 기물 클래스들을 선언하였습니다.
- 각 Piece의 타입을 받아와 해당하는 체스 기물 객체의 인스턴스를 생성해 반환합니다.

- createWhite(), createBlack() 호출시 메서드명의 가독성을 위해 중복을 감안하고 분리하였습니다.
- 요구사항을 준수하였습니다.
- 가독성을 향상 시키고자 나눴던 메소드가 오히려 코드를 더 복잡하게 만들고, 기존 테스트 케이스도 재활용할 수 없어 다시 원래 메소드로 회귀 하였습니다.
- 호출 시 아규먼트가 많아지다보니 복잡해져서 메소드를 분리해보았습니다.
- 요구사항의 테스트를 작성하였습니다.
- 비어있는 체스 슬롯을 표현하기 위한 상수입니다.
- piece의 색이 none이 아닌 것들을 모두 카운터한 후 리턴합니다.
- findPiece() 메소드를 통해, Index에 해당하는 기물 객체를 찾고, 그에 맞는 기호를 가져옵니다.

- 8 요소 마다 개행이 필요하므로, 객체를 가져올 때마다 개수를 카운트하며, 카운트가 8에 도달하면 개행을 합니다.
- move와 같은 추상 메소드를 만들기 위해 추상 클래스를 생각했지만, 지금 당장은 없는 기능이기 때문에 class로 정의 하였습니다.
@LarryJung LarryJung self-assigned this Feb 25, 2021
@LarryJung LarryJung self-requested a review February 25, 2021 09:57
Copy link

@LarryJung LarryJung left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

구현 잘 하셨습니다~
공부하셨으면 미리 적용해 보셔도 좋습니다. ㅎㅎ 이미 미션의 중반 이상이기 때문에.. 그럴 수 있다고 생각이 드네요^^

상속을 사용한 부분에서 같은 기능과 같은데이터를 한곳으로 모아놓은 목적 정도로 보이는데요, 그런 이유라면 꼭 상속을 사용할 이유가 없습니다 (상속vs합성 을 찾아보세요)
리뷰 중 isYou() 라는 메서드를 제시해 드렸으니, 이 것을 한번 구현해보시면서 상속구조를 사용했을 때 어떤 이점이 있을 지 생각해주시면 좋을것 같습니다. ^^ 하다가 다르게 바꿔보셔도 좋습니다.

position 의 책임에 관해..
이 것은 어떻게 해도 상관 없습니다! 먼저 가장 쉽게 돌아가는 코드를 짠 후에 리팩토링을 하면서 제 자리를 찾아가도록 하시면 됩니다 ㅎㅎ

Comment on lines 35 to 44
public String appendPawnRep(UnitColor color) {
StringBuilder pawnLine = new StringBuilder();
for (Pawn pawn : pawns) {
if (pawn.isColor(color)) {
for (Piece pawn : pieces) {
boolean classCheck = pawn.getClass().getSimpleName().equalsIgnoreCase(UnitType.PAWN.name());
if (pawn.isColor(color) && classCheck) {
pawnLine.append(pawn.getRepresentation());
}
}
return pawnLine.toString();
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 메서드 조금 개선해보면 좋을 것 같습니다.
일단 pieces 포문인데 아이템 변수 이름이 pawn -> piece가 되어야 할 것 같구요,

포문 블럭을 아래처럼 짜보면 상속구조를 좀 더 이용하게 되실 거에요~

for (Piece piece : this.pieces) {
  if (piece.isYou(color, UnitType.PAWN)) {
    pawnLine.append(piece.getRepresentation());
  }
}

boolean classCheck 을 각 객체에게 위임한 꼴이라고 생각하시면 될것 같습니다. :)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

반영해서 PUSH 완료하였습니다.😍
이전보다 훨씬 간결해져서 너무 좋네요 ㅎㅎ
아직 자바 초심자라서 추상적인 내용보다 이러한 레퍼런스가 좀 더 학습에 있어 이해도가 높고 오래 기억에 남는 것 같습니다. 감사합니다.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

코드는 아래와 같이 작성하였습니다.

    public boolean isYou(UnitColor unitColor, UnitType unitType) {
        boolean classCheck = this.getClass().getSimpleName().equalsIgnoreCase(unitType.name());
        return isColor(unitColor) && classCheck;
    }

Copy link

@LarryJung LarryJung Feb 26, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

한번만 더 개선해볼 수 있을까요?ㅎㅎ
힌트를 드리자면..

  1. Piece를 추상클래스로 선언
  2. isYou 메서드를 추상메서드로 만들고 각 자식 클래스에서 구현

요 조건으로요!

리플랙션을 이용해서 클래스 이름을 직접 꺼내는 것은 위험한 코딩방식 중 하나에요,
왜냐하면 클래스이름이 변경되면 로직도 수정을 해야하기 때문인데요,
위 방식으로 개선을 해 보시겠어용?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

맞습니다.😂
기존에 NO_PIECE라는 클래스 이름이 있었는데, 클래스 명명규칙에 맞지 않는 것 같아 None으로 재정의 하였다가
당시에는 문제를 모르고 나중에 테스트 할 때 오류가 났는데, 클래스 이름을 바꾼걸 깜박해서 오류 파악을 제대로 못하고 "왜 오류가나지?" 라고 생각하고, 계속 다른곳만 삽질 했었습니다...👻

리뷰어님 리뷰 반영하여 Pieces 클래스를 추상 클래스로 선언하였고, 아래와 같이 각 클래스마다 추상 메서드를 구현해주었습니다. 기존의 파일 이름을 사용하는 방식보다 훨씬 이해하기 쉬운 코드가 된 것 같아 기분이 좋습니다.😀😍

@Override
  public boolean isYou(UnitColor unitColor, UnitType unitType) {
      return UnitType.BISHOP == unitType && super.isColor(unitColor);
  }
  • PUSH 완료했습니다!

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

현재는 아래와 같이 리팩토링을 진행하였습니다.

    public boolean isBishop(UnitColor unitColor){
        return (isType(UnitType.BISHOP) && isColor(unitColor));
    }

Comment on lines 103 to 116
public String showBoard() {
StringBuilder boardString = new StringBuilder();
final int LINE_OF_PIECE = 8;
int count = 1;
for (int col = 0; col < pieces.size(); col++) {
if (count == LINE_OF_PIECE) {
boardString.append(findPiece(col).getRepresentation()).append(StringUtils.NEWLINE);
count = 1;
} else {
boardString.append(findPiece(col).getRepresentation());
count++;
}
}
return boardString.toString();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

기회가 되신다면 재귀로 한번 짜보시는것도.. 추천드립니다. ㅎㅎ

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

말씀하신 사항 반영해서 PUSH를 했습니다.
하지만, 제가 재귀함수를 많이 안해봐서 올바르게 했는지 잘 모르겠습니다.
한번 검토해주시면 감사하겠습니다.

public StringBuilder showBoard(int index, int count) {
        final StringBuilder boardString = new StringBuilder();
        final int LINE_OF_PIECE = 8;

        if (index == 63) {
            return boardString.append(findPiece(index).getRepresentation()).append(StringUtils.NEWLINE);
        }

        if (count == LINE_OF_PIECE) {
            count = 0;
            return boardString.append(findPiece(index).getRepresentation()).append(StringUtils.NEWLINE).append(showBoard(index + 1, count + 1));
        }
        return boardString.append(findPiece(index).getRepresentation()).append(showBoard(index + 1, count + 1));
    }

와 같이 구현하였고

System.out.println(board.showBoard(0, 1).toString());

와 같이 호출이 가능합니다.
showBoard() argument 중 count가 1인 이유는 체스 라인 8개를 직관적으로 카운트하기 위함이었습니다.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

넵 확인했습니다. 잘 짜셨구요! 포문은 전부 재귀로 변경할 수 있다는 것만 알려드리고 싶었어요.

재귀는 포문의 단점을 보완하는 방식이지만 주의점도 있으니 사용할때 주의할 점도 있답니다. (재귀vs공재귀 개념이 있습니다. 아직 깊게 안들어가셔도 되어용)
체스 미션에서 요구되는 개념은 아니었지만 도전과제로 코멘트 드렸습니다. ^^

Copy link
Author

@sanhee sanhee Feb 26, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

재귀는 스택에 메모리가 계속 쌓여서 메모리가 부족하기 쉬워,
이러한 문제를 해결하기 위해 각 연산 단계마다 즉시 계산하는 공재귀를 사용할 수 있다는 것을 알게되었습니다.

그래서 아래같이 StringBuilder 를 정적변수로 선언 해서 해볼까 했는데..

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space

을 확인할 수 있었습니다 ㅋㅋ...

🔔 혹시 공재귀에 대한 자바 예제 샘플은 어디서 학습할 수 있을까요??
구글에 공재귀를 검색을 해보면 코틀린에 대한 포스트가 많은 것 같아, 전체적으로 이해하기 어려워 질문을 드리게 되었습니다.

 static final StringBuilder boardString = new StringBuilder();

    public StringBuilder showBoard(int index, int count) {
        final int LINE_OF_PIECE = 8;

        if (index == 63) {
            return boardString.append(findPiece(index).getRepresentation()).append(StringUtils.NEWLINE);
        }

        if (count == LINE_OF_PIECE) {
            count = 0;
            return boardString.append(findPiece(index).getRepresentation()).append(StringUtils.NEWLINE).append(showBoard(index + 1, count + 1));
        }
        return boardString.append(findPiece(index).getRepresentation()).append(showBoard(index + 1, count + 1));
    }


import net.sanhee.pieces.property.UnitColor;

public class PieceFactory {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

팩토리 클래스를 공부하셨군요~😀

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

학습하고 미션에 바로 적용해서 올바르게 활용 했는지 잘 모르겠습니다.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

잘 사용하셨습니다. 눈으로 보기 좋았으면 어느정도는 성공입니다. ㅎㅎㅎ


public enum UnitColor {
BLACK, WHITE, NONE;
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

파일 끝 개행 넣어주세요^^

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

파일 끝 개행에 대해 처음 알게 되었는데, 키워드 알려주셔서 감사합니다.
말씀하신 사항 반영하여 PUSH 하였습니다!

Comment on lines 104 to 105
StringBuilder boardString = new StringBuilder();
final int LINE_OF_PIECE = 8;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

상수값 뿐 아니라 StringBuilder도 final 을 사용할 수 있겠죠? 생각해보면 특정하게 변수의 재할당이 필요한 몇몇 경우를 제외하고는 final을 붙여줄 수 있는 대상들이 많이 있습니다. ㅎㅎ

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

말씀하신 사항 반영하여 PUSH를 하긴 했는데,
질문사항🖐이 있습니다!

StringBuilder, List 등 final을 하면 내부 변수를 변경할 수 있는데 해야 하는 이유에 대해서??
예시 또는 키워드를 알려주시면 감사하겠습니다.

제가 검색했던 키워드는 :

  • 자바 fianl stringbuilder list
  • 자바 final
  • 자바 fianl을 붙일 수 있는 대상

등 이었는데 원하는 결과를 찾지 못했습니다.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오늘 그룹원에게 같은 질문을 해봤는데,
참조하고 있는 객체에 대한 주소를 변경하지 못하게 하는 것으로,
객체지향 프로그래밍에서 캡슐화를 이루기 위해 최대한 제한을 두는 거라는 의견이 모였는데,
틀린 의견이 있을까요??

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

final 이 하는 역할은 메모리 주소의 재할당 (쉽게 말해서 변수의 재할당) 을 못하게 하는 것입니다.

개인적인 선호 때문인것도 있는데용~ 저는 변수가 재할당이 필요할까? 생각하셔서 그럴일이 없을것 같다. 앞으로도 없어야 안전할 것 같다 라고 생각하면 final 을 보통 붙입니다. 왜냐면 값의 변경 가능성을 최대한 닫아두는 것이 좀 더 안전한 코드라고 생각하기 때문입니다.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이번을 계기로 final 개념을 정리 할 수 있었습니다.
답변 감사합니다!!

Comment on lines 5 to 9
public class Bishop extends Piece {
public Bishop(UnitColor color) {
super(color);
}
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

상속은 이렇게 사용하면 됩니다. ㅎㅎ 다만 아쉬운 점이 하나 있는데 최종 코멘트에서 남기도록 하겠습니다.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

상속관계일떄 조상클래스에 isYou() 메서드를 추가하니까 모든 자식 클래스에서 동일하게 사용할 수 있어 코드 중복이 줄어드는 것을 확인할 수 있었습니다.
상속을 했던 것은 체스 객체들이 많은 정보를 공통으로 사용하고 move나 point같은 일부 요소만 다를거라고 생각했기 때문에 상속을 사용했었습니다.

Comment on lines 18 to 33
public static char getMark(UnitColor color, String unitClassName) {
char mark = ' ';

switch (color) {
case BLACK:
mark = Character.toUpperCase(UnitType.valueOf(unitClassName.toUpperCase()).unitRepresentation);
break;
case WHITE:
mark = Character.toLowerCase(UnitType.valueOf(unitClassName.toUpperCase()).unitRepresentation);
break;
case NONE:
mark = UnitType.valueOf(unitClassName.toUpperCase()).unitRepresentation;
break;
}
return mark;
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

어느 것이 더 나은지는 판단해주세요~ switch 할때 이렇게도 할 수 있을 것 같네요

public static char getMark(UnitColor color, String unitClassName) {
        final char mark;

        switch (color) {
            case BLACK:
                mark = Character.toUpperCase(UnitType.valueOf(unitClassName.toUpperCase()).unitRepresentation);
                break;
            case WHITE:
                mark = Character.toLowerCase(UnitType.valueOf(unitClassName.toUpperCase()).unitRepresentation);
                break;
            case NONE:
                mark = UnitType.valueOf(unitClassName.toUpperCase()).unitRepresentation;
                break;
            default:
                mark = ' ';
        }
        return mark;
    }
  • default를 두지 않고 변수 선언 시 기본값을 채워주기
  • final 로 두고 특정 케이스에만 값을 할당하고 나머지 경우도 default로 메꾸기

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

enum을 학습할 때, switch문에서 default를 사용하지 않아도 된다는 내용을 보아서
특별한 생각없이 작성한 것 같습니다.
리뷰어님이 말씀하신 것처럼 특정 케이스에서만 값을 할당하고, final로 상수 지정해두는 것이 좀더 안전할 것 같습니다.

  • PUSH 완료했습니다!

- LarryJung 리뷰어님의 추천으로 한번 구현해보게 되었습니다.
- 재귀함수를 직접 구현해본 적이 얼마 없어 잘 작성했는지 모르겠지만 최선을 다해 작성하였습니다!
- LarryJung님의 리뷰를 반영하여, 특정 케이스에서만 값을 할당하는 방식을 채택했습니다.
@sanhee
Copy link
Author

sanhee commented Feb 25, 2021

말씀하신 사항 반영하여 PUSH 완료 했습니다.

🤠질문사항1 #150 (comment)
😀질문사항2 #150 (comment)
😎질문사항3. 체스 코드에서 포함관계를 사용했을 때, 간단한 예시를 알고싶습니다.

  • 자바의 정석 교재에서는 is a , has a 과 같이 어떤 관계일 때 상속 또는 포함관계를 사용하라고 돼있어, 완벽히 이해하지 못했습니다.
  • Pawn, Rook 같은 체스 객체 클래스들을 각자 만들어두고 Piece 안에 넣는건가요??..너무 기초적인 질문이라서 죄송합니다.

@LarryJung
Copy link

말씀하신 사항 반영하여 PUSH 완료 했습니다.

🤠질문사항1 #150 (comment)
😀질문사항2 #150 (comment)
😎질문사항3. 체스 코드에서 포함관계를 사용했을 때, 간단한 예시를 알고싶습니다.

  • 자바의 정석 교재에서는 is a , has a 과 같이 어떤 관계일 때 상속 또는 포함관계를 사용하라고 돼있어, 완벽히 이해하지 못했습니다.
  • Pawn, Rook 같은 체스 객체 클래스들을 각자 만들어두고 Piece 안에 넣는건가요??..너무 기초적인 질문이라서 죄송합니다.

답글이 많이 늦어서 죄송합니다~ㅠ
수정사항은 확인했구요 ㅎㅎ 조금 더 코멘트를 드렸습니다.

is a, has a 관계를 생각해서 상속을 해야할지 어떻게 해야할 지 판단하실 수도 있는데요,
어느 자바교재에서는 상속을 아예 자제하라는 말도 있습니다. 즉 상속은 모두 합성으로 대체할 수도 있다는 것인데요 ㅎㅎ

현재 코드에서 상속을 해서 얻는 이점이 적다는 것을 보여드리면..
제가 아래처럼 Piece가 UnitType 을 받는거로 로직을 수정하면, isYou 메서드 구현부도 간결해지고 굳이 상속을 했어야 할 이유는 없어 보이죠?

public class Piece {

    private final UnitType unitType;
    private final UnitColor color;
    private final char representation;

    public Piece(UnitColor color, UnitType unitType) {
        this.unitType = unitType;
        this.color = color;
        //m 생성자 매게변수를 줄이기 위해, 호출한 클래스의 이름을 활용하였습니다.
        this.representation = UnitType.getMark(this.color, this.getClass().getSimpleName());
    }

    public UnitColor getColor() {
        return color;
    }

    public char getRepresentation() {
        return representation;
    }

    public boolean isColor(UnitColor color) {
        return this.getColor().equals(color);
    }

    public boolean isBlack() {
        return this.getColor() == UnitColor.BLACK;
    }

    public boolean isWhite() {
        return this.getColor() == UnitColor.WHITE;
    }

    public boolean isYou(UnitColor unitColor, UnitType unitType) {
        return isColor(unitColor) && this.unitType == unitType ;
    }
}

이렇게 되면 굳이 표현하자면
Piece를 상속하는 자식객체를 만들지 않고, UnitType 이란 멤버 변수를 합성해서 문제를 해결한 꼴이 되는 거에요~

- LarryJung 님의 리뷰를 통해, 기존의 클래스 이름을 활용하는 방식이 좋지 못한 방법이란 것을 깨닫게 되어, 수정하게 되었습니다.
- 기존 상속을 받아 생성했던, 복수개의 체스 유닛 클래스를 제거하였습니다.
- PieceFactory 클래스는 큰 의미가 없어 제거하였습니다.
- Piece 클래스에 UnitColor와 UnitType을 가지게하여 포함관계를 만들었습니다.
- Piece 클래스의 생성자를 private으로 선언하여 직접 생성을 제한하였습니다.
- Piece 클래스 메서드에 팩토리 메서드를 구현하여, 객체에 이름을 부여하였습니다.
- 이식 뒤 모든 테스트 케이스가 기존과 같이 통과 했음을 확인했습니다.
@sanhee
Copy link
Author

sanhee commented Feb 27, 2021

... 생략

Piece를 상속하는 자식객체를 만들지 않고, UnitType 이란 멤버 변수를 합성해서 문제를 해결한 꼴이 되는 거에요~

생각해보니 아직 단계에서는 다수의 체스 유닛 클래스가 필요하지 않은 것 같아 불필요한 클래스를 제거하고,
Piece 내부에 타입과 컬러 변수를 합성해서 구현해보았습니다. 636c54c

포함관계가 어떻게 이루어지는 것인지 잘 몰랐었는데, 설명해주셔서 많은 이해를 할 수 있었습니다.

혹시 제가 잘못한 점이 있다면 지적해주시면 감사하겠습니다!

  • 기존처럼 클래스 이름으로 구분하는 코드가 사라지니, 훨씬 가독성이 좋아진 것 같습니다 ㅎㅎ

그리고 또 질문사항🖐이 생겨서 답글을 달았는데 확인해주시면 정말 감사하겠습니다!

@sanhee
Copy link
Author

sanhee commented Mar 3, 2021

@honux77
호눅스님! 혹시 merge 해주실 수 있나요??
리뷰어님이 바쁘신거 같아서요!!
다음 PR을 하게된다면.. 그때 마저 반영하겠습니다!

@honux77 honux77 merged commit b6b9c41 into codesquad-members-2021:sanhee Mar 3, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants