Skip to content

박정제 1주차 체스 학습 일지

CodingLuizy edited this page Jul 1, 2024 · 1 revision

객체지향적으로 설계를 하는건 어떤걸까?

  • SOLID, OOP ...

객체마다의 역할과 책임을 잘 분리해두는것 그렇다면, 핵심 관심사가 무엇이고, 그것을 유연하게 잘 적용하려면 어떻게 해야할까?

💡 핵심 관심사 : 규칙적용

  • 모든 이동은 규칙에 따라 이동한다 (행마법, 캐슬링…)
  • 제일 오랫동안 집중적으로 구현할 부분이 규칙이동이라고 생각
  • 규칙을 enum 으로 정의하고 규착마다의 이동 방식을 구현하는 방법으로 구현

Enum 활용기

출처 : Java Enum 활용기

Java Enum 활용기 요약

기본적인 장점:

  • IDE 지원: 자동완성, 오타 검증, 텍스트 리팩토링 등.
  • 허용 값 제한: 허용 가능한 값을 제한.
  • 리팩토링 최소화: 변경 범위 최소화.
  • 추가 수정 불필요: Enum 코드 외 수정 불필요.

추가적인 Java Enum의 장점:

  • Java의 Enum은 완전한 클래스 기능을 가짐.

예제 소개:

  1. 데이터 연관관계 표현:

    • 문제: 서로 다른 데이터 형태("Y"/"N", "1"/"0", true/false) 사용.
    • 해결: Enum으로 추출하여 데이터 그룹화.
    public enum TableStatus {
        YES("Y", "1", true),
        NO("N", "0", false);
        // ... getter methods
    }
  2. 상태와 행위를 한곳에서 관리:

    • 문제: 다른 계산식을 적용하는 메소드 관리 어려움.
    • 해결: Enum을 통해 각 상태가 자체 계산식을 갖도록 지정.
    public enum Calculator {
        CALC_A {
            @Override
            public long calculate(long input) { return input; }
        },
        CALC_B {
            @Override
            public long calculate(long input) { return input + 10; }
        },
        CALC_C {
            @Override
            public long calculate(long input) { return input * 3; }
        };
        public abstract long calculate(long input);
    }
  3. 데이터 그룹 관리:

    • 문제: 결제 종류와 결제 수단 관계를 문자열과 메소드로 관리.
    • 해결: Enum을 사용하여 관계 명확히 표현.
    public enum PayGroup {
        CARD("신용카드", Arrays.asList("페이코", "카카오페이")),
        CASH("현금", Arrays.asList("계좌이체", "휴대폰결제"));
        // ... methods for managing pay codes
    }
  4. 관리 주체를 DB에서 객체로 전환:

    • 문제: 코드 테이블을 DB에서 관리하면서 발생하는 문제점.
    • 해결: 카테고리 데이터를 Enum으로 전환하고, 팩토리와 인터페이스로 일관된 관리.
    public enum Category implements BaseEnum {
        FOOD("음식"), ELECTRONICS("전자제품");
        // ... implementation of BaseEnum interface
    }

결론:

  • 장점: 코드 이해도와 유지보수성 향상, 문맥(Context) 표현 가능.
  • 추가 고려사항: 자주 변경되는 데이터는 별도로 관리 필요.

마무리:

  • Enum을 통해 코드의 가독성과 유지보수성을 높이며, 실용적이고 효율적인 개발이 가능함.

구현

기물

  • 기물을 일반화 시킨 Piece.class 구현
classDiagram
direction BT
class Bishop {
  + double DEFAULT_POINT
  + char WHITE_REPRESENTATION
  + char BLACK_REPRESENTATION
}
class King {
  + char BLACK_REPRESENTATION
  + double DEFAULT_POINT
  + char WHITE_REPRESENTATION
}
class Knight {
  + char WHITE_REPRESENTATION
  + char BLACK_REPRESENTATION
  + double DEFAULT_POINT
}
class Pawn {
  + char WHITE_REPRESENTATION
  + char BLACK_REPRESENTATION
  + double DEFAULT_POINT
}
class Piece {
  # List~Direction~ movableDirections
  # List~MoveRule~ specialMoveRules
  # Color color
  # char representation
  + int MAX_MOVE_DISTANCE
  - boolean isMoved
  # int moveDistance
}
class Queen {
  + char BLACK_REPRESENTATION
  + double DEFAULT_POINT
  + char WHITE_REPRESENTATION
}
class Rook {
  + char WHITE_REPRESENTATION
  + char BLACK_REPRESENTATION
  + double DEFAULT_POINT
}

Bishop  -->  Piece
King  -->  Piece
Knight  -->  Piece
Pawn  -->  Piece
Queen  -->  Piece
Rook  -->  Piece

Loading
  • 각 기물들은 각각의 특성들을 가지고 있다
    • 이동 방향과 이동 거리 : 행마법에 따른 움직임
    • 특수한 이동 규칙 : 폰의 이동, 캐슬링 등

이동규칙

  • 모든 기물의 이동은 규칙에 따라 이동한다
  • MoveRule enum class로 이동규칙을 정의하고 각 enum class에 이동방식과 이동을 구현했다.
  • chess/move/MoveRule.java
public enum MoveRule{
    Common {
        public void move(Board board, String source, String target) {}
        public Map<ChessPoint, MoveRule> getMovablePoints(Board board, ChessPoint source, Piece piece) {}
    },
    Castling {
        public void move(Board board, String source, String target) {}
        public Map<ChessPoint, MoveRule> getMovablePoints(Board board, ChessPoint kingPoint, Piece piece) {}

        @Override
        public boolean isAttackable() {return false;}

    },
    PawnMove {
        public void move(Board board, String source, String target) {}
        public Map<ChessPoint, MoveRule> getMovablePoints(Board board, ChessPoint source, Piece piece) {}
    },
    Promotion {
        public void move(Board board, String source, String target) {}
        public Map<ChessPoint, MoveRule> getMovablePoints(Board board, ChessPoint source, Piece piece) {}
    },
    None {
        public void move(Board board, String source, String target) {}
        public Map<ChessPoint, MoveRule> getMovablePoints(Board board, ChessPoint source, Piece piece) {}
    };

    public void adapt(Map<ChessPoint, MoveRule> map, Board board, ChessPoint source, Piece piece, boolean onlyAttackable) {
        if (onlyAttackable) {
            if (this.isAttackable()) {
                map.putAll(this.getMovablePoints(board, source, piece));
            }
        }
        else {
            map.putAll(this.getMovablePoints(board, source, piece));
        }
    }

    public abstract void move(Board board, String source, String target);

    public abstract Map<ChessPoint, MoveRule> getMovablePoints(Board board, ChessPoint source, Piece piece);

    public boolean isAttackable() {
        return true;
    }
}
  • 따라서, 각 기물에 적용되는 규칙만 알고 있으면 된다.

이동

  • 'Board' 클래스의 move 메소드를 통해 기물을 이동시킨다.
  • 출발 위치의 기물이 목적위치까지 이동할 수 있는 규칙을 찾아 이동시킨다.
  • chess/Board.java
public void move(String source, String target) {
    Piece piece = findPiece(source);
    MoveRule moveRule = piece.getMoveRule(this, ChessPoint.of(source), ChessPoint.of(target));
    moveRule.move(this, source, target);
}
  • 이동 가능한 위치인지 파악하기 위해서는 MoveRule을 적용한다
  • chess/piece/Piece.java

👼 개인 활동을 기록합시다.

개인 활동 페이지

🧑‍🧑‍🧒‍🧒 그룹 활동을 기록합시다.

그룹 활동 페이지

🎤 미니 세미나

미니 세미나

🤔 기술 블로그 활동

기술 블로그 활동

📚 도서를 추천해주세요

추천 도서 목록

🎸 기타

기타 유용한 학습 링크

Clone this wiki locally