Publish:

νƒœκ·Έ: ,

μΉ΄ν…Œκ³ λ¦¬:

이전 κΈ€μ—μ„œ 계측ꡬ쑰λ₯Ό κ°€μ§€λŠ” 메뉴에 μ»΄ν¬μ§€νŠΈ νŒ¨ν„΄μ„ μ μš©ν•΄λ΄€λ‹€. 이번 κΈ€μ—μ„œλŠ” μΆ”μƒν΄λž˜μŠ€λ₯Ό μ μš©ν•΄ 곡톡기λŠ₯ μΆ”μΆœ 및 μžλ™ν™” ν•΄λ³Έλ‹€.

문제

ν˜„μž¬κΉŒμ§€ μž‘μ—…ν•œ μ†ŒμŠ€μ—μ„œ BoardAddHandler, BoardDeleteHandler, BoardListHandler, BoardViewHandler, BoardModifyHandler λ“± 각 λ„λ©”μΈμ˜ ν•Έλ“€λŸ¬λ§ˆλ‹€ κ³΅ν†΅μœΌλ‘œ μ€‘λ³΅λ˜λŠ” μ†ŒμŠ€μ½”λ“œκ°€ μžˆλ‹€.

1
2
3
4
5
6
7
8
9
10
11
  public class BoardAddHandler implements MenuHandler {

  ...

  @Override
  public void action(Menu menu) {
    System.out.printf(AnsiEscape.ANSI_BOLD + "[%s]\n" + AnsiEscape.ANSI_CLEAR, menu.getTitle());

    ...
  }
}

μΈν„°νŽ˜μ΄μŠ€μ— μ •μ˜λœ action(Menu menu) μΆ”μƒλ©”μ†Œλ“œλ₯Ό κ΅¬ν˜„ν•΄μ„œ μž¬μ •μ˜ ν–ˆμ§€λ§Œ 아직 μ€‘λ³΅μ½”λ“œκ°€ 남아 μžˆλŠ” μƒνƒœλ‹€. 이 뢀뢄을 μΆ”μΆœν•˜κ³ μž ν•œλ‹€.

클래슀 λ‹€μ΄μ–΄κ·Έλž¨

μœ„ 클래슀 λ‹€μ΄μ–΄κ·Έλž¨ 처럼 concrete class(κ΅¬μƒν΄λž˜μŠ€) μ—μ„œ μ§μ ‘μ μœΌλ‘œ μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•˜μ§€ μ•Šκ³  쀑간에 λΆ€λͺ¨ ν΄λž˜μŠ€κ°€ 일뢀 κ΅¬ν˜„ν•˜κ²Œ ν•œλ‹€. (Generalization) 그리고 ꡬ상 ν΄λž˜μŠ€λŠ” λΆ€λͺ¨ν΄λž˜μŠ€λ₯Ό μƒμ†λ°›λŠ”λ‹€. μ΄λŠ” μΈν„°νŽ˜μ΄μŠ€μ— μ •μ˜λœ μΆ”μƒλ©”μ†Œλ“œκ°€ λ§Žμ€ 경우 κ΅¬μƒν΄λž˜μŠ€μ—μ„œ λ©”μ†Œλ“œ μž¬μ •μ˜λ₯Ό ν•΄μ•Όν•˜λŠ” 뢀담을 쀄여쀀닀.

AbstractMenuHandler

1
2
3
4
5
6
7
8
9
10
11
12
13
14
  public class AbstractMenuHandler implements MenuHandler {
  
    protected Menu menu;
  
    @Override
    public void action(Menu menu) {
      this.printMenuTitle(menu.getTitle());
    }
  
    private void printMenuTitle(String title) {
      System.out.printf(AnsiEscape.ANSI_BOLD + "[%s]\n" + AnsiEscape.ANSI_CLEAR, title);
    }
  
  }

각 ν•Έλ“€λŸ¬μ—μ„œ μ€‘λ³΅λ˜λŠ” μ½”λ“œλ₯Ό μΆ”μΆœν•΄ λΆ€λͺ¨ν΄λž˜μŠ€μ—μ„œ κ΅¬ν˜„ν•˜λ„λ‘ ν–ˆλ‹€.

BoardAddHandler

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
  public class BoardAddHandler extends AbstractMenuHandler {

    private ArrayList<Board> objectRepository;
    private Prompt prompt;
  
    public BoardAddHandler(ArrayList<Board> objectRepository, Prompt prompt) {
      this.prompt = prompt;
      this.objectRepository = objectRepository;
    }
  
    @Override
    protected void action(Menu menu) { // MenuHandler μΈν„°νŽ˜μ΄μŠ€ μΆ”μƒλ©”μ†Œλ“œ μž¬μ •μ˜
      super.action(menu) // λΆ€λͺ¨ν΄λž˜μŠ€μ— 일뢀 κ΅¬ν˜„λœ action λ©”μ†Œλ“œ 호좜
      Board board = new Board();
      board.setTitle(this.prompt.input("제λͺ©? "));
      board.setContent(this.prompt.input("λ‚΄μš©? "));
      board.setWriter(this.prompt.input("μž‘μ„±μž? "));
      board.setCreatedDate(this.prompt.input("μž‘μ„±μΌ? "));
  
      objectRepository.add(board);
    }
  }

κ΅¬μƒν΄λž˜μŠ€μ—μ„œλŠ” κΈ°μ‘΄ λ©”μ†Œλ“œμ— super.action(menu) λ₯Ό μΆ”κ°€ν•΄ λΆ€λͺ¨ ν΄λž˜μŠ€μ— μ •μ˜λœ 곡톡 μ†ŒμŠ€μ½”λ“œλ₯Ό ν˜ΈμΆœν•˜κ²Œ ν•œ ν›„ μ΄μ–΄μ„œ μž‘μ—…ν•˜κ²Œλœλ‹€. 이전보닀 μ’€ 더 객체지ν–₯ μŠ€λŸ¬μ›Œμ§€κΈ΄ ν–ˆμœΌλ‚˜ μ—¬μ „νžˆ λ¬Έμ œκ°€ λ‚¨μ•„μžˆλ‹€.

λ©”μ†Œλ“œλ₯Ό μž¬μ •μ˜ν•˜λŠ” κ³Όμ •μ—μ„œ super.action(menu) 을 ν•„μˆ˜λ‘œ ν˜ΈμΆœν•΄μ•Ό ν•œλ‹€. κ°œλ°œμžκ°€ μ‹€μˆ˜λ‘œ μž‘μ„±ν•˜μ§€ μ•ŠλŠ” 경우λ₯Ό 미연에 방지할 μˆ˜κ°€ μ—†λ‹€. μ½”λ“œ 확인

μˆ˜μ •λœ AbstractMenuHandler

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
  public abstract class AbstractMenuHandler implements MenuHandler {
    
    protected Prompt prompt; // 이것도 κ΅¬μƒν΄λž˜μŠ€μ—μ„œ κ³΅ν†΅μ μœΌλ‘œ μ“°μ΄λ―€λ‘œ μΆ”μƒν΄λž˜μŠ€μ—μ„œ μ„ΈνŒ…ν•˜λ„λ‘ ν•œλ‹€.
    protected Menu menu;

    public AbstractMenuHandler(Prompt prompt) {
      this.prompt = prompt;
    }
    
    @Override
    public void action(Menu menu) {
      this.printMenuTitle(menu.getTitle());
      this.menu = menu; // μ„œλΈŒν΄λž˜μŠ€ κ΅¬ν˜„ μ‹œ μ‚¬μš©ν•  일이 있으면 μ“Έ 수 μžˆλ„λ‘ 보관해 λ‘”λ‹€.
      
      // Menu λ₯Ό μ‹€ν–‰ν•  λ•Œ 이 λ©”μ†Œλ“œκ°€ 호좜되면 μ¦‰μ‹œ μ„œλΈŒ 클래슀의 action() λ©”μ†Œλ“œλ₯Ό ν˜ΈμΆœν•œλ‹€.
      this.action();
    }
  
    private void printMenuTitle(String title) {
      System.out.printf(AnsiEscape.ANSI_BOLD + "[%s]\n" + AnsiEscape.ANSI_CLEAR, title);
    }

    // μ„œλΈŒν΄λž˜μŠ€κ°€ κ΅¬ν˜„ν•΄μ•Ό ν•  λ©”μ†Œλ“œ. μ™ΈλΆ€μ—μ„œ ν˜ΈμΆœν•  λ©”μ†Œλ“œκ°€ μ•„λ‹ˆλ‹€(protected)
    protected abstract void action(); 
}

AbstractMenuHandler 에 action() 좔상 λ©”μ†Œλ“œλ₯Ό μ •μ˜ν•˜κ³  좔상 클래슀둜 λ³€κ²½ν–ˆλ‹€. 그리고 κΈ°μ‘΄ μΈν„°νŽ˜μ΄μŠ€μ—μ„œ κ΅¬ν˜„ν•œ action(Menu menu) μ—μ„œ 이 λ©”μ†Œλ“œλ₯Ό ν˜ΈμΆœν•˜κ²Œ ν•œλ‹€.

μˆ˜μ •λœ BoardAddHandler

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
  public class BoardAddHandler extends AbstractMenuHandler {

  private ArrayList<Board> objectRepository;

  public BoardAddHandler(ArrayList<Board> objectRepository, Prompt prompt) {
    super(prompt);
    this.objectRepository = objectRepository;
  }

  @Override
  protected void action() { // AbstractMenuHandler μΆ”μƒλ©”μ†Œλ“œ μž¬μ •μ˜
    Board board = new Board();
    board.setTitle(this.prompt.input("제λͺ©? "));
    board.setContent(this.prompt.input("λ‚΄μš©? "));
    board.setWriter(this.prompt.input("μž‘μ„±μž? "));
    board.setCreatedDate(this.prompt.input("μž‘μ„±μΌ? "));

    objectRepository.add(board);
  }
}

AbstractMenuHandler λ₯Ό 상속받은 ν΄λž˜μŠ€λŠ” μΆ”μƒλ©”μ†Œλ“œλ₯Ό ν•„μˆ˜μ μœΌλ‘œ κ΅¬ν˜„ν•΄μ•Ό ν•œλ‹€.

κΈ°μ‘΄μ—λŠ” MenuHandler μΈν„°νŽ˜μ΄μŠ€λ₯Ό 직접 κ΅¬ν˜„ν•΄ μ‚¬μš©ν–ˆμ§€λ§Œ μˆ˜μ •λœ μ½”λ“œμ—μ„œλŠ” μΈν„°νŽ˜μ΄μŠ€μ™€ κ΅¬μƒν΄λž˜μŠ€ 쀑간에 μžˆλŠ” AbstractMenuHandler 의 λ©”μ†Œλ“œλ₯Ό μž¬μ •μ˜ν•΄μ„œ μ‚¬μš©ν•˜κ²Œ λœλ‹€. μ½”λ“œ 확인

싀행흐름

As-is

1
2
3
4
5
  App ν΄λž˜μŠ€μ—μ„œ 메뉴 호좜(execute())
                  β¬‡οΈŽ
  MenuItem 의 action(menu) μ‹€ν–‰
                  β¬‡οΈŽ
  MenuHandler λ₯Ό κ΅¬ν˜„ν•œ BoardAddHandler μ—μ„œ action(menu) μ‹€ν–‰

To-be

1
2
3
4
5
6
7
  App ν΄λž˜μŠ€μ—μ„œ 메뉴 호좜(execute())
                  β¬‡οΈŽ
  MenuItem 의 action(menu) μ‹€ν–‰
                  β¬‡οΈŽ
  MenuHandler λ₯Ό κ΅¬ν˜„ν•œ AbstractMenuHandler μ—μ„œ action(menu) μ‹€ν–‰
                  β¬‡οΈŽ
  AbstractMenuHandler λ₯Ό 상속받은 BoardAddHandler μ—μ„œ action() μ‹€ν–‰

기쑴의 MenuHandler λ₯Ό κ΅¬ν˜„ν•œ BoardAddHandler μ—μ„œ action(menu) μ‹€ν–‰ 이 뢀뢄을 λΆ„λ¦¬ν•œ 것이라 보면 λœλ‹€. java api λŠ” μ΄λŸ°μ‹μœΌλ‘œ μΈν„°νŽ˜μ΄μŠ€λ₯Ό 일뢀 κ΅¬ν˜„ν•œ μΆ”μƒν΄λž˜μŠ€λ₯Ό 쀑간에 두고 이λ₯Ό μƒμ†λ°›μ•„μ„œ λ§Œλ“œλŠ” 객체듀이 λ§Žλ‹€.

λ°©λ¬Έν•΄ μ£Όμ…”μ„œ κ°μ‚¬ν•©λ‹ˆλ‹€! λŒ“κΈ€,지적,ν”Όλ“œλ°± μ–Έμ œλ‚˜ ν™˜μ˜ν•©λ‹ˆλ‹€πŸ˜Š

λŒ“κΈ€λ‚¨κΈ°κΈ°