μƒνƒœ νŒ¨ν„΄μ΄λž€?


μƒνƒœ νŒ¨ν„΄μ΄λž€, 일련의 κ·œμΉ™μ— 따라 객체의 μƒνƒœλ₯Ό λ³€ν™”μ‹œμΌœ 객체가 ν•  수 μžˆλŠ” ν–‰μœ„λ₯Ό λ°”κΎΈλŠ” 것을 μ˜λ―Έν•œλ‹€.

즉, λ™μΌν•œ λ©”μ„œλ“œλ₯Ό 객체의 μƒνƒœμ— 따라 λ‹€λ₯΄κ²Œ λ™μž‘ν•  수 μžˆλ„λ‘ ν•˜λŠ” 것이닀.

객체의 μƒνƒœλ₯Ό λ³„λ„μ˜ νƒ€μž…μœΌλ‘œ λΆ„λ¦¬ν•˜κ³  μƒνƒœ 별 ν•˜μœ„ νƒ€μž…μ„ κ΅¬ν˜„ν•˜μ—¬ μ‚¬μš©ν•œλ‹€.

좔상화 된 λ™μΌν•œ λ©”μ„œλ“œμ— μƒνƒœλ§ˆλ‹€ λ‹€λ₯Έ νŠΉμ • κΈ°λŠ₯을 μˆ˜ν–‰ν•œ ν›„ λ‹€μŒ μƒνƒœλ₯Ό λ°˜ν™˜ν•˜λŠ” 것이 핡심이닀.

μƒνƒœ νŒ¨ν„΄ 적용


μΈν„°νŽ˜μ΄μŠ€

public interface BoardState {
 
    boolean isEnd();
 
    boolean isBlackTurn();
 
    Winner findWinner();
 
    BoardState move(Position start, Position target);
 
    Rank getRank(int rankLine);
 
    BoardState terminate();
 
    double calculateBlackScore();
 
    double calculateWhiteScore();
}

체슀 λ―Έμ…˜μ„ μ§„ν–‰ν•˜λ©΄μ„œ 체슀 κ²Œμž„μ˜ μƒνƒœλ₯Ό μƒνƒœ νŒ¨ν„΄μ„ μ μš©ν•˜μ—¬ κ΅¬ν˜„ν•΄λ³΄κ³ μž ν–ˆλ‹€.

객체의 μƒνƒœμ— 따라 λ‹¬λΌμ§€λŠ” ν–‰μœ„λ₯Ό 좔상화 된 ν˜•νƒœλ‘œ μΈν„°νŽ˜μ΄μŠ€λ₯Ό λ§Œλ“ λ‹€.

  • 체슀 κ²Œμž„μ΄ λλ‚¬λŠ”μ§€ ν™•μΈν•˜λŠ” κΈ°λŠ₯
  • ν˜„μž¬ μ°¨λ‘€κ°€ ν‘νŒ€μΈμ§€ ν™•μΈν•˜λŠ” κΈ°λŠ₯
  • 승리자λ₯Ό μ°ΎλŠ” κΈ°λŠ₯
  • 기물을 μ›€μ§μ΄λŠ” κΈ°λŠ₯
  • 체슀판의 κ°€λ‘œμ€„μ„ κ°€μ Έμ˜€λŠ” κΈ°λŠ₯
  • 체슀 κ²Œμž„μ„ κ°•μ œ μ’…λ£Œν•˜λŠ” κΈ°λŠ₯
  • ν‘νŒ€μ˜ 점수λ₯Ό κ³„μ‚°ν•˜λŠ” κΈ°λŠ₯
  • λ°±νŒ€μ˜ 점수λ₯Ό κ³„μ‚°ν•˜λŠ” κΈ°λŠ₯

μœ„ κΈ°λŠ₯듀은 체슀 κ²Œμž„μ΄ 진행 μ€‘μ΄κ±°λ‚˜ μ’…λ£Œ λ˜μ—ˆμ„ λ•Œ, ν‘νŒ€μ˜ μ°¨λ‘€μ΄κ±°λ‚˜ λ°±νŒ€μ˜ 차둀일 λ•Œ λ‹€λ₯΄κ²Œ 행동할 수 μžˆλ‹€.

좔상 클래슀

κ΅¬ν˜„ν•˜κ³ μž ν•˜λŠ” μƒνƒœ 쀑 μ€‘λ³΅λ˜λŠ” ν–‰μœ„κ°€ μžˆλ‹€λ©΄ μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•œ 좔상 클래슀λ₯Ό λ§Œλ“€μ–΄ μ‚¬μš©ν•œλ‹€.

좔상 클래슀둜 μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•  경우 μΈν„°νŽ˜μ΄μŠ€μ— μœ„μΉ˜ν•œ λͺ¨λ“  λ©”μ„œλ“œλ₯Ό μ˜€λ²„λΌμ΄λ”©ν•  ν•„μš” 없이 μ€‘λ³΅λ˜λŠ” λ©”μ„œλ“œλ§Œμ„ κ΅¬ν˜„ν•  수 μžˆλ‹€.

public abstract class GameStarted implements BoardState {
 
    protected final Map<Integer, Rank> ranks;
 
    public GameStarted(Map<Integer, Rank> ranks) {
        this.ranks = ranks;
    }
 
    public Rank getRank(int rankLine) {
        return ranks.get(rankLine);
    }
}

체슀 κ²Œμž„μ˜ λͺ¨λ“  μƒνƒœμ—μ„  μ²΄μŠ€νŒμ„ μ˜λ―Έν•˜λŠ” ranks λ₯Ό λͺ¨λ‘ ν¬ν•¨ν•˜κ³  있기 λ•Œλ¬Έμ— μΈν„°νŽ˜μ΄μŠ€ λ°”λ‘œ μ•„λž˜μ— GameStarted λΌλŠ” 좔상 클래슀λ₯Ό κ΅¬ν˜„ν•˜μ—¬ λͺ¨λ“  ν•˜μœ„ νƒ€μž… μƒνƒœμ—μ„œ ranks λ₯Ό μ‚¬μš©ν•  수 μžˆλ„λ‘ κ΅¬ν˜„ν–ˆλ‹€.

public abstract class Playing extends GameStarted {
 
    public Playing(Map<Integer, Rank> ranks) {
        super(ranks);
    }
 
    BoardState movePiece(Position start, Position target) {
        // ...
    }
 
    Piece getPiece(Position position) {
        // ...
    }
 
    @Override
    public boolean isEnd() {
        return false;
    }
 
    @Override
    public Winner findWinner() {
        throw new IllegalStateException();
    }
 
    @Override
    public BoardState terminate() {
        return new Terminate(ranks);
    }
 
    @Override
    public double calculateBlackScore() {
        throw new IllegalStateException();
    }
 
    @Override
    public double calculateWhiteScore() {
        throw new IllegalStateException();
    }
}

GameStarted λ₯Ό μƒμ†λ°›λŠ” 또 λ‹€λ₯Έ 좔상 클래슀인 Playing 이닀.

쑰상인 GameStarted ν΄λž˜μŠ€μ—μ„œ 체슀판의 κ°€λ‘œμ€„μ„ κ°€μ Έμ˜€λŠ” κΈ°λŠ₯을 κ΅¬ν˜„ν–ˆκΈ° λ•Œλ¬Έμ— Playing μ—μ„œλŠ” ν•΄λ‹Ή κΈ°λŠ”μ„ μ œμ™Έν•œ κΈ°λŠ₯듀을 κ΅¬ν˜„ν•˜λ©΄ λœλ‹€.

Playing 은 체슀 κ²Œμž„μ΄ μ§„ν–‰λ˜κ³  μžˆλŠ” μƒνƒœλ₯Ό μ˜λ―Έν•œλ‹€. λ•Œλ¬Έμ— μ’…λ£Œ λ˜μ—ˆμ„ λ•Œ μ‹€ν–‰λ˜μ–΄μ•Ό ν•˜λŠ” 일뢀 ν–‰μœ„λ“€μ€ λͺ¨λ‘ μ˜ˆμ™Έλ₯Ό λ˜μ§€λ„λ‘ μ²˜λ¦¬ν•œλ‹€.

Playing 의 ν•˜μœ„ μƒνƒœλ‘œλŠ” WhiteTurn κ³Ό BlackTurn 이 μ‘΄μž¬ν•œλ‹€.

ν•΄λ‹Ή μƒνƒœλ§ˆλ‹€ λ‹€λ₯΄κ²Œ κ΅¬ν˜„λ  수 μžˆλŠ” λ©”μ„œλ“œλ“€μ€ κ΅¬ν˜„ν•˜μ§€ μ•ŠλŠ”λ‹€.

μƒνƒœ 클래슀

체슀 κ²Œμž„ λ‚΄μ—μ„œ μ‚¬μš©λ˜λŠ” μƒνƒœλŠ” μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•˜κ±°λ‚˜ μΆ”μƒν΄λž˜μŠ€λ₯Ό 상속받아 ν•΄λ‹Ή μƒνƒœλ§Œ κ°€μ§ˆ 수 μžˆλŠ” ν–‰μœ„λ₯Ό μž¬μ •μ˜ν•˜μ—¬ μ‚¬μš©ν•  수 μžˆλ‹€.

public final class WhiteTurn extends Playing {
 
    public WhiteTurn(Map<Integer, Rank> ranks) {
        super(ranks);
    }
 
    @Override
    public boolean isBlackTurn() {
        return false;
    }
 
    @Override
    public BoardState move(Position start, Position target) {
        // ...
    }
 
    @Override
    public End judgeWinner() {
        return new WhiteWin(ranks);
    }
 
    @Override
    public Playing judgeTurn() {
        return new BlackTurn(ranks);
    }
 
    @Override
    public String findTurn() {
        return "λ°±";
    }
}
public final class BlackTurn extends Playing {
 
    public BlackTurn(Map<Integer, Rank> ranks) {
        super(ranks);
    }
 
    @Override
    public boolean isBlackTurn() {
        return true;
    }
 
    @Override
    public BoardState move(Position start, Position target) {
        // ...
    }
 
    @Override
    public End judgeWinner() {
        return new BlackWin(ranks);
    }
 
    @Override
    public Playing judgeTurn() {
        return new WhiteTurn(ranks);
    }
 
    @Override
    public String findTurn() {
        return "흑";
    }
}

체슀 κ²Œμž„ 진행 쀑 λ°±νŒ€κ³Ό ν‘νŒ€μ˜ μ°¨λ‘€λ₯Ό λ‚˜νƒ€λ‚΄κΈ° μœ„ν•œ WhiteTurn κ³Ό BlackTurn 이닀.

μƒνƒœμ— 따라 λ‹€λ₯΄κ²Œ λ™μž‘ν•˜λŠ” λ©”μ„œλ“œλ“€μ„ ν•΄λ‹Ή 클래슀 λ‚΄λΆ€μ—μ„œ κ΅¬ν˜„ν•΄μ€€λ‹€.

이λ₯Ό 톡해 Context μΈ‘μ—μ„œλŠ” BoardState λ§Œμ„ μ°Έμ‘°ν•˜μ—¬ ν˜„μž¬ 체슀 κ²Œμž„μ˜ μƒνƒœλ₯Ό μ•Œ ν•„μš” 없이 ν•„μš”ν•œ κΈ°λŠ₯듀을 ν˜ΈμΆœν•΄μ£ΌκΈ°λ§Œ ν•˜λ©΄ λœλ‹€.

μƒνƒœ νŒ¨ν„΄μ˜ μž₯단점


μž₯점

  • Context 내뢀에 μ‘΄μž¬ν•˜λŠ” 뢄기문듀을 μ œκ±°ν•  수 μžˆλ‹€.
  • μΆ”κ°€μ μœΌλ‘œ μš”κ΅¬λ˜λŠ” μƒνƒœλ„ μƒνƒœ 객체λ₯Ό μƒˆλ‘­κ²Œ κ΅¬ν˜„ν•˜μ—¬ μ μš©ν•  수 μžˆλ‹€.
  • 클래슀 κ°œμˆ˜λŠ” μ¦κ°€ν•˜μ§€λ§Œ μ½”λ“œμ˜ λ³΅μž‘λ„λŠ” μ¦κ°€ν•˜μ§€ μ•ŠκΈ° λ•Œλ¬Έμ— μœ μ§€λ³΄μˆ˜μ— μš©μ΄ν•˜λ‹€.

단점

  • Context μƒνƒœ λ³€ν™”μ˜ 주체일 경우, μƒνƒœμ˜ κ°œμˆ˜κ°€ λ§Žμ•„μ§€κ±°λ‚˜ μƒνƒœ λ³€κ²½ κ·œμΉ™μ΄ 자주 λ³€κ²½λœλ‹€λ©΄ Context λ‚΄λΆ€μ˜ μ½”λ“œκ°€ λ³΅μž‘ν•΄μ§ˆ 수 있고, λΆˆν•„μš”ν•œ λ©”μ„œλ“œκ°€ μƒνƒœ 객체 내뢀에 생길 수 μžˆλ‹€.
  • μƒνƒœ 객체가 μƒνƒœ λ³€ν™”μ˜ 주체일 경우, μƒνƒœ λ³€κ²½ κ·œμΉ™μ΄ μ—¬λŸ¬ ν΄λž˜μŠ€μ— λΆ„μ‚°λ˜μ–΄ 있기 λ•Œλ¬Έμ— μƒνƒœ 객체가 λ§Žμ•„μ§ˆμˆ˜λ‘ μƒνƒœ λ³€κ²½ κ·œμΉ™μ„ νŒŒμ•…ν•˜κΈ° μ–΄λ €μ›Œμ§ˆ 수 있고, 각 μƒνƒœ κ°„ μ˜μ‘΄λ„κ°€ 생길 수 μžˆλ‹€.

μ „λž΅ νŒ¨ν„΄κ³Όμ˜ 차이점


곡톡점

μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ‚¬μš©ν•˜μ—¬ κ΅¬ν˜„ 클래슀λ₯Ό μΊ‘μŠν™”ν•œλ‹€. 즉, λ‹€ν˜•μ„±κ³Ό 좔상 λ©”μ„œλ“œλ₯Ό ν™œμš©ν•˜μ—¬ Context μ—μ„œλŠ” μ–΄λ–€ ν•˜μœ„ 클래슀λ₯Ό ν• λ‹Ήλ°›λŠ”μ§€ μ•Œμ§€ λͺ»ν•˜λŠ” μƒνƒœλ‘œ λ‹¨μˆœνžˆ 좔상 λ©”μ„œλ“œλ₯Ό μ‹€ν–‰ν•œλ‹€.

Context λ‚΄λΆ€λŠ” 영ν–₯을 받지 μ•Šκ³  μœ μ—°ν•˜κ²Œ 변화에 λŒ€μ²˜ν•  수 μžˆλ‹€.

차이점

μ „λž΅ νŒ¨ν„΄μ˜ 경우, μ™ΈλΆ€λ‘œλΆ€ν„° μ „λž΅μ΄ μ£Όμž…λ˜μ–΄μ•Ό ν•œλ‹€. 상황에 맞좰 행동을 μ£Όμž…ν•˜μ—¬ μ‹€ν–‰ν•  수 μžˆλ‹€.

λ‹€μ–‘ν•œ μ•Œκ³ λ¦¬μ¦˜μ„ 상황에 따라 μ‚¬μš©ν•΄μ•Ό ν•˜λŠ” 경우 κ³ λ €ν•΄λ³Ό 수 μžˆλ‹€.

μƒνƒœ νŒ¨ν„΄μ˜ 경우, λ‚΄λΆ€μ—μ„œ 슀슀둜 Context 의 μƒνƒœλ₯Ό λ³€κ²½ν•  수 μžˆλ‹€.

λ‹€μ–‘ν•œ μƒνƒœ λ³€ν™”λ₯Ό 닀뀄야할 경우. 즉, 뢄기문이 λ§Žμ•„ λ³΅μž‘ν•  경우 κ³ λ €ν•΄λ³Ό 수 μžˆλ‹€.

References