[Java] λ©λ΄ νλͺ©μ Stack μΌλ‘ κ΄λ¦¬νκΈ° (feat.ν©ν 리 λ©μλ)
νκ·Έ: Java, Refactoring
μΉ΄ν κ³ λ¦¬: Java
- μ΄μ κΈμ μ΄μ΄μ λ©λ΄λ₯Ό Stack μΌλ‘ κ΄λ¦¬νλλ‘ μμ ν΄ λ³Έλ€.
- ν©ν 리λ©μλλ₯Ό μ μ©ν΄ κ°μ²΄ μμ±μ κ΄ν μ½λλ₯Ό μ¨κΈ°κ³ , μ’ λ μλ―Έμλ μ΄λ¦μ λ©μλλ₯Ό μ 곡νλ€.
Stack ꡬν
μ΄λμ μ μ₯νλλκ° μλλΌ μ΄λ»κ² κ°μ Έμ¬ κ²μΈκ°μ μ΄μ μ λ§μΆ°μ μ§ννλ―λ‘, κΈ°μ‘΄μ λ§λ€μλ λ§ν¬λ리μ€νΈλ₯Ό μ΄μ©ν΄ Stack μ κ°λ¨ν ꡬννλ€. λ°°μ΄μ μ΄μ©ν΄ ꡬνν΄λ μκ΄μλ€.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class Stack<E> extends LinkedList<E> {
public E push(E value) {
add(value);
return value;
}
public E pop() {
return remove(size() - 1);
}
public E peek() {
return get(size() - 1);
}
public boolean empty() {
return size() == 0;
}
}
μ€νμ κΈ°λ³Έμ μΈ νΉμ§μ νμ
μ μΆ(Last-In First-Out)μ΄λ€.
μ΄μ κ°μ νΉμ§μ μΉλΈλΌμ°μ νμ μ λ€λ‘κ°κΈ°
λ λλ리기(ctrl + z)
μ κ°μ κΈ°λ₯μ ꡬνν λ μ©μ΄νλ€.
Stack μ λ£μλλ μμ°¨μ μΌλ‘ λ€μ΄κ°κ³ Stack μμ λΉ μ Έλμ¬λλ κ°μ₯ μ΅κ·Ό μμ
λΆν° μμμΌλ‘ λΉ μ Έλμ¨λ€.
μ΄λ₯Ό λ©λ΄ μ§μ
μ 보μ¬μ£Όλ Prompt
μ μ μ©ν΄ 보μ. λ©λ΄λ₯Ό μ§μ
ν λ μμ°¨μ μΌλ‘ λνλ΄κ³ , λ μ΄μ μΌλ‘ λμκ°λλ κ·Έ μμμΌλ‘ 보μ¬μ€λ€.
As-is
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[λ©μΈ]
1. κ³Όμ
2. κ²μκΈ
3. νμ
4. κ°μ
μΈμ¬
5. λμλ§
0. μ΄μ
λ©μΈ> 1
[κ³Όμ ]
1. λ±λ‘
2. μ‘°ν
3. λ³κ²½
4. μμ
5. λͺ©λ‘
0. μ΄μ
κ³Όμ > <---- μ΄ λΆλΆμ Stack μΌλ‘ κ΄λ¦¬νλ€.
λ©μΈ λ©λ΄μμ νμ λ©λ΄λ‘ μ§μ
μ μ
λ ₯ μ°½μ νμ¬ μ΄λκΉμ§ μ§μ
νλμ§ νμκ° λμ§ μκ³ μλ€.
MenuGroup
μμ±μμμ title μ λ°μ κ·Έλλ‘ μΆλ ₯λ§ ν΄μ£Όκ³ μκΈ° λλ¬Έμ΄λ€.
MenuGroup
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class MenuGroup extends AbstractMenu {
// μμ±μμμ title λ°μ
public MenuGroup(String title) {
super(title);
}
@Override
public void execute(Prompt prompt) {
this.printMenu();
while (true) { // title μ¬μ©
String input = prompt.input("%s> ", this.getTitle());
...
}
}
}
App
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class App {
public static void main(String[] args) throws Exception {
Prompt prompt = new Prompt(System.in);
ArrayList<Board> boardRepository = new ArrayList<>();
ArrayList<Assignment> assignmentRepository = new ArrayList<>();
ArrayList<Member> memberRepository = new ArrayList<>();
ArrayList<Board> greetingRepository = new ArrayList<>();
MenuGroup mainMenu = new MenuGroup("λ©μΈ");
MenuGroup boardMenu = new MenuGroup("κ²μκΈ");
boardMenu.add(new MenuItem("λ±λ‘", new BoardAddHandler(boardRepository, prompt)));
boardMenu.add(new MenuItem("μ‘°ν", new BoardViewHandler(boardRepository, prompt)));
boardMenu.add(new MenuItem("λ³κ²½", new BoardModifyHandler(boardRepository, prompt)));
boardMenu.add(new MenuItem("μμ ", new BoardDeleteHandler(boardRepository, prompt)));
boardMenu.add(new MenuItem("λͺ©λ‘", new BoardListHandler(boardRepository, prompt)));
mainMenu.add(boardMenu);
....
}
}
App
ν΄λμ€μμ μ§μ κ°μ²΄λ₯Ό μμ±νλ μ½λκ° λ§μ΄ ν¬ν¨λμ΄ μλ€. μ κ°μ²΄λ₯Ό μμ±ν΄μΌ νλμ§ λΆλΆλͺ
νκ³ κ΅³μ΄ μ νμλ μλ€. μ½λμ κ°λ
μ±μ΄ λ¨μ΄μ§κ³ 볡μ‘ν΄ λ³΄μΈλ€.
To-be
MenuGroup
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
public class MenuGroup extends AbstractMenu {
...
// μμ±μμμ Stack μ λ°λλ€.
private MenuGroup(String title, Stack<String> breadcrumb) {
super(title, breadcrumb);
}
// ν©ν 리 λ©μλλ₯Ό μ΄μ©ν΄ μΈμ€ν΄μ€λ₯Ό λ°ννλ€.
public static MenuGroup getInstance(String title) {
return new MenuGroup(title, new Stack<>());
}
@Override
public void execute(Prompt prompt) {
// λ©λ΄λ₯Ό μ€νν λ λ©λ΄μ μ λͺ©μ breadcrumb μ μΆκ°νλ€.
breadcrumb.push(title);
this.printMenu();
while (true) {
String input = prompt.input("%s> ", this.getMenuPath());
if (input.equals("menu")) {
this.printMenu();
continue;
} else if (input.equals("0")) {
break;
}
try {
int menuNo = Integer.parseInt(input);
if (menuNo < 1 || menuNo > menus.size()) {
System.out.println("λ©λ΄ λ²νΈκ° μ³μ§ μμ΅λλ€.");
continue;
}
this.menus.get(menuNo - 1).execute(prompt); // μ€νν λλ§λ€ Stack μ push λλ€.
} catch (Exception e) {
System.out.println("λ©λ΄κ° μ³μ§ μμ΅λλ€");
}
}
breadcrumb.pop(); // λ©λ΄ λκ°λ λ©λ΄ μ λͺ©μ μ κ±°νλ€.
}
// App μ μ’λ μ§κ΄μ μΈ μ½λλ₯Ό μ 곡νκΈ° μν νΈμμ± λ©μλ
public MenuItem addItem(String title, MenuHandler handler) {
MenuItem menuItem = new MenuItem(title, handler, breadcrumb);
add(menuItem);
return menuItem;
}
// App μ μ’λ μ§κ΄μ μΈ μ½λλ₯Ό μ 곡νκΈ° μν νΈμμ± λ©μλ
public MenuGroup addGroup(String title) {
MenuGroup menuGroup = new MenuGroup(title, breadcrumb);
add(menuGroup);
return menuGroup;
}
}
App
μμ MenuGroup
μ νΈμΆν λ Stack μ λ§λ€μ΄ AbstractMenu
λ‘ μ λ¬ν΄ μ€λ€.
κ°μ²΄ μμ±μ λν μ½λλ ν©ν 리 λ©μλλ₯Ό μ΄μ©νλ€.
μμ±μλ₯Ό μ§μ νΈμΆνκΈ° λ³΄λ€ μλ―Έμλ μ΄λ¦ μ κ°μ§ ν©ν 리 λ©μλλ₯Ό ν΅ν΄ λ°ννλλ‘ νλκ²μ΄ μ½λ κ°λ
μ±μ μ’λ€.
λν μμ±μλ₯Ό private
λ‘ μ€μ ν΄ ν©ν 리 λ©μλμμλ§ κ°μ²΄ μμ±μ΄ κ°λ₯νλλ‘ ν μ μλ€.
App
ν΄λμ€μμ μλμκ°μ΄ getInstance
λ₯Ό νΈμΆνλ©΄μ βλ©μΈβ μ΄λΌλ λ©λ΄ μ λͺ©μ μμ±μλ‘ μ£Όμ
νλ€. μ΄λ Stack κ°μ²΄λ ν¨κ» λ§λ€μ΄ μ£Όμ
ν΄μ€λ€.
1
MenuGroup mainMenu = MenuGroup.getInstance("λ©μΈ");
λ©λ΄ μ
λ ₯μ λ°λ excute
κ° μ΅μ΄ νΈμΆλλ©΄ μ μ½λμμ μμ±μλ‘ λ°μμ νλλ‘ κ°μ§κ³ μλ λ©λ΄ title μ Stack μ λ£λλ€.
νμ¬ Stack μλ βλ©μΈβμ΄ λ€μ΄κ° μλ μνκ° λλ€.
1
2
int menuNo = Integer.parseInt(input);
this.menus.get(menuNo - 1).execute(prompt);
μ΄ν μ
λ ₯ν λ©λ΄ λ²νΈμ λ°λ₯Έ title μ΄ κ³μν΄μ Stack μ push λλ€. breadcrumb μ getMenuPath()
μμ λ§λ€μ΄μ§λ€.
1
2
3
4
// Stack μμ λ©λ΄λͺ©λ‘μ κ°μ Έμ 쑰립νλ€.
public String getMenuPath() {
return String.join("/", breadcrumb.toArray(new String[0]));
}
menus
λͺ©λ‘μ App
ν΄λμ€μμ addItem
κ³Ό addGroup
μ΄ νΈμΆλ λλ§λ€ μ μ₯λλ€.
1
2
3
4
5
6
7
8
MenuGroup mainMenu = MenuGroup.getInstance("λ©μΈ");
MenuGroup boardMenu = mainMenu.addGroup("κ²μκΈ");
boardMenu.addItem("λ±λ‘", new BoardAddHandler(boardRepository, prompt));
boardMenu.addItem("μ‘°ν", new BoardViewHandler(boardRepository, prompt));
boardMenu.addItem("λ³κ²½", new BoardModifyHandler(boardRepository, prompt));
boardMenu.addItem("μμ ", new BoardDeleteHandler(boardRepository, prompt));
boardMenu.addItem("λͺ©λ‘", new BoardListHandler(boardRepository, prompt));
App
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
public class App {
public static void main(String[] args) throws Exception {
Prompt prompt = new Prompt(System.in);
List<Board> boardRepository = new LinkedList<>();
List<Assignment> assignmentRepository = new LinkedList<>();
List<Member> memberRepository = new ArrayList<>();
List<Board> greetingRepository = new ArrayList<>();
MenuGroup mainMenu = MenuGroup.getInstance("λ©μΈ");
MenuGroup boardMenu = mainMenu.addGroup("κ²μκΈ");
boardMenu.addItem("λ±λ‘", new BoardAddHandler(boardRepository, prompt));
boardMenu.addItem("μ‘°ν", new BoardViewHandler(boardRepository, prompt));
boardMenu.addItem("λ³κ²½", new BoardModifyHandler(boardRepository, prompt));
boardMenu.addItem("μμ ", new BoardDeleteHandler(boardRepository, prompt));
boardMenu.addItem("λͺ©λ‘", new BoardListHandler(boardRepository, prompt));
MenuGroup memberMenu = mainMenu.addGroup("νμ");
memberMenu.addItem("λ±λ‘", new MemberAddHandler(memberRepository, prompt));
memberMenu.addItem("μ‘°ν", new MemberViewHandler(memberRepository, prompt));
memberMenu.addItem("λ³κ²½", new MemberModifyHandler(memberRepository, prompt));
memberMenu.addItem("μμ ", new MemberDeleteHandler(memberRepository, prompt));
memberMenu.addItem("λͺ©λ‘", new MemberListHandler(memberRepository, prompt));
MenuGroup greetingMenu = mainMenu.addGroup("κ°μ
μΈμ¬");
greetingMenu.addItem("λ±λ‘", new BoardAddHandler(greetingRepository, prompt));
greetingMenu.addItem("μ‘°ν", new BoardViewHandler(greetingRepository, prompt));
greetingMenu.addItem("λ³κ²½", new BoardModifyHandler(greetingRepository, prompt));
greetingMenu.addItem("μμ ", new BoardDeleteHandler(greetingRepository, prompt));
greetingMenu.addItem("λͺ©λ‘", new BoardListHandler(greetingRepository, prompt));
mainMenu.addItem("λμλ§", new HelpHandler(prompt));
// jvm κΉμ§ μ€λ₯λ³΄κ³ μκ°κ² λ§κΈ°
while (true) {
try {
mainMenu.execute(prompt);
prompt.close();
break;
} catch (Exception e) {
System.out.println("main() μμΈ λ°μ");
}
}
μνΈλ¦¬ν¬μΈνΈκ° λλ App
ν΄λμ€μμμ μ½λκ° μ’ λ μ§κ΄μ μ΄κ³ μλ―Έλ₯Ό μμλ³Ό μ μλ λ©μλλ€λ‘ λ³νλ€.
λκΈλ¨κΈ°κΈ°