[๋์์ธํจํด] ์ดํฐ๋ ์ดํฐ ํจํด(Iterator Pattern)
ํ๊ทธ: Design Pattern, Java, Refactoring
์นดํ ๊ณ ๋ฆฌ: Design Pattern
- ์ดํฐ๋ ์ดํฐ์ ๋ํด ์์๋ณธ๋ค.
- ์ดํฐ๋ ์ดํฐ ํจํด ์ ์ฉ ์ ์ฅ์ ๊ณผ ๋จ์ ๋ฐ ๊ฐ์ ๋ฐฉํฅ์ ์์๋ณธ๋ค.
์ดํฐ๋ ์ดํฐ(Iterator)๋?
์๋ฃ๊ตฌ์กฐ๋ง๋ค ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๋ ๋ฐฉ์์ด ๋ค๋ฅด๋ค๋ณด๋ ๋ฐ์ดํฐ๋ฅผ ๊บผ๋ด๋ ๋ฐฉ๋ฒ ๋ํ ๋ค๋ฅด๋ค. ์์ฐจ์ ์ผ๋ก ์ ๊ทผ ๊ฐ๋ฅํ ์๋ฃ๊ตฌ์กฐ์ ๊ฒฝ์ฐ, for ๋ฌธ์ ํตํด ๊ฐ์ ธ์ค๋ฉด ๋์ง๋ง
Set
์ด๋ Map
๋ฑ์ ๋ฐ์ดํฐ์ ์์๋ฅผ ์ ์ฅํ์ง ์๋๋ค. ์ด๋ฌํ ์๋ฃ๊ตฌ์กฐ์ ๊ฒฝ์ฐ ๋ฐ์ดํฐ๋ฅผ ์กฐํํ๊ธฐ ์ํด ํ์์๊ณ ๋ฆฌ์ฆ์ ์ด์ฉํด์ผ ํ๋ค.
๊ฐ๊ฐ์ ์๋ฃ๊ตฌ์กฐ๋ง๋ค ๋ฐ์ดํฐ๋ฅผ ์กฐํํ๊ธฐ ์ํ ๋ฐฉ์์ ์ผ๊ด์ฑ์ด ์๋ค.
์ด๋ ๊ฒ ์๋ฃ๊ตฌ์กฐ์ ํน์ฑ์ ์ ํํ ์ดํดํด์ผ๋ง ์ฌ์ฉ๊ฐ๋ฅํ ์กฐํ ๋ฐฉ์์ ๋๋ฌด ๋นํจ์จ์ ์ด๋ค.
์ดํฐ๋ ์ดํฐ ํจํด์ ์ง์ ์๋ฃ๊ตฌ์กฐ์ ์ ๊ทผํด ๊บผ๋ด๋ ๋ฐฉ์์ด ์๋, ๊ฐ์ ๊บผ๋ด์ฃผ๋ ์ผ์ ๋์ ํ๋ ํด๋์ค๋ฅผ ๋ง๋ค๊ณ ์ด๋ฅผ ํตํด ๊ฐ์ ๊บผ๋ธ๋ค. ์ดํฐ๋ ์ดํฐ๋ฅผ ์ฐ๋ ๊ฒฝ์ฐ ๋ฐ์ดํฐ๋ฅผ ์ผ๊ด๋ ๋ฐฉ์์ผ๋ก ์กฐ์ํ ์ ์์ด ํธ๋ฆฌํ๋ค.
java Collection๋ค์ iterable ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ๊ณ ์๋ค.
์ธํฐํ์ด์ค ์ ์
๊ธฐ์กด์ ๋ง๋ค์๋ List
์ธํฐํ์ด์ค์ ๋ฐ์ดํฐ ์กฐํ๋ฅผ ์ผ๊ด์ฑ์๊ฒ ํ๊ธฐ ์ํ iterator()
๊ท์น์ ์ถ๊ฐํ๋ค. ์ด์ ๋ถํฐ ์๋ฃ๊ตฌ์กฐ์ ์๊ด์์ด ๋ฐ์ดํฐ๋ฅผ ์กฐํํ ๋ Iterator()
๋ฅผ ๊ตฌํํด์ ์ฌ์ฉํ๋ฉด ๋๋ค.
1
2
3
4
public interface List<E> {
...
Iterator<E> iterator();
}
์ธํฐํ์ด์ค ๊ตฌํ์ฒด
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class LinkedListIterator<E> implements Iterator<E> {
LinkedList<E> list;
int cursor;
public LinkedListIterator(LinkedList<E> list) {
this.list = list;
}
@Override
public boolean hasNext() {
return cursor >= 0 && cursor < list.size();
}
@Override
public E next() {
return list.get(cursor++);
}
}
๊ตฌ์ฒด์ ์ธ ์กฐํ ๋ฐฉ์์ ์ฌ์ฉํ๋ ์๋ฃ๊ตฌ์กฐ์ ๋ง๊ฒ Iterator
์ธํฐํ์ด์ค๋ฅผ ํตํด ๊ตฌํํ๋ค. ํด๋น ์ฝ๋์์๋ LinkedList
์์ ์ฌ์ฉํ ๋ชฉ์ ์ผ๋ก ๊ตฌํํ๋ค.
hasNext()
๋ ๋ฐ๋ณตํ ํญ๋ชฉ์ด ๋จ์๋์ง ํ์ธํ๋ ์ฉ๋๋ก ์ฌ์ฉํ๊ณ ์ค์ ๊ฐ์ ๊ฐ์ ธ์ค๋ ์์
์ next()
๋ฅผ ํตํด ๊ฐ์ ธ์ค๋ฉด ๋๋ค. ํธ์ถ๋ถ์์ ๋์ ์ ์ ํ ์ฌ์ฉํด ๋ฐ์ดํฐ๋ฅผ ์กฐํํ๊ฒ ๋๋ค.
LinkedList ์ ๋ฐ๋ณต์ ๊ตฌํํ๊ธฐ
1
2
3
4
5
6
7
8
9
public class LinkedList<E> extends AbstractList<E> {
...
@Override
public Iterator<E> iterator() {
return new LinkedListIterator<>(this);
}
...
}
ํ์ฌ LinkedList
๋ List
์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ AbstractList
ํด๋์ค๋ฅผ ์์๋ฐ์ ๋ง๋ค๊ณ ์์ผ๋ฏ๋ก, ๋ฉ์๋๋ฅผ ์ฌ์ ์ ํด์ค๋ค. ๊ตฌํ๋ถ์๋ ์๊น ๋ง๋ค์ด๋์ ๋ฐ๋ณต์(LinkedListIterator
)๋ฅผ ๋ฐํํด์ฃผ๋ ์ฝ๋๋ฅผ ์์ฑํ๋ค.
LinkedListIterator
์์ LinkedList
์ ์ ๊ทผํ๊ธฐ ์ํด์ ์์ฑ์๋ก ์ดํฐ๋ ์ดํฐ๋ฅผ ์ฌ์ฉํ๊ณ ์ ํ๋ ์ธ์คํด์ค๋ฅผ ์ฃผ์
ํด ์ค์ผ ํ๋ค.
LinkedList
ํด๋์ค๊ฐ ํธ์ถ๋๋ฉด์ ์ดํฐ๋ ์ดํฐ๋ ์ฌ์ฉ๋ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ this
๋ก ์ฃผ์
ํด ์ฃผ๋ฉด ๋๋ค.
๊ทธ๋ฌ๋ฉด LinkedListIterator
๋ ํธ์ถ๋ ๋๋ง๋ค ์๋ก์ด LinkedList
๊ฐ์ฒด๋ฅผ ๋ฐ์ ์ฒ์๋ถํฐ(cursor) ๋ฆฌ์คํธ ์ฌ์ด์ฆ๋งํผ(list.size()) ์ํํ๋ฉด์ ๊ฐ์ ์ฐพ์ ๊ฒ์ด๋ค.
์ด์ LinkedList
๋ ๋ฐ์ดํฐ ์กฐํ๋ฅผ ์ํ ์๋ก์ด ๊ธฐ๋ฅ์ ๊ฐ์ถ๊ฒ ๋์๋ค!
LinkedList
๋ฅผ ์ฌ์ฉํ๊ณ ์๋ ๊ณณ์์ ์๋์ฒ๋ผ ๋ฐ๋ณต์๋ฅผ ์์ฑํด ๋ฐ์ดํฐ๋ฅผ ์กฐํํ๋ค.
1
new LinkedList<>().iterator();
Iterator ๋ฅผ ์ด์ฉํด ๋ฐ์ดํฐ ์กฐํํ๊ธฐ
As-is
1
2
3
4
5
6
7
8
9
private void printMenu() {
System.out.printf("[%s]\n", this.getTitle());
for (int i = 0; i < this.menus.size(); i++) {
System.out.printf("%d. %s\n", (i + 1), menus.get(i).getTitle());
}
System.out.printf("0. %s\n", "์ด์ ");
}
ํ์ฌ printMenu()
๋ฉ์๋๋ ๋ค์๊ณผ ๊ฐ์ด ๋ฐ๋ณต๋ฌธ์ ์ด์ฉํด LinkedList
์ get()
๋ฉ์๋์ ์ง์ ์ ๊ทผํ๊ณ ์๋ค. ๋ง์ฝ list
ํ์
์ด ์๋๋ผ hashMap
๊ฐ์ ์๋ฃ๊ตฌ์กฐ๋ก ๋ฉ๋ด์ถ๋ ฅ์ ํ๋๋ก ๋ณ๊ฒฝ๋๋ค๋ฉด ํด๋น ์์ค์ฝ๋๋ ๋ณ๊ฒฝํด์ผ ํ๋ค.
To-be
1
2
3
4
5
6
7
8
9
10
11
12
private void printMenu() {
System.out.printf("[%s]\n", this.getTitle());
Iterator<Menu> iterator = this.menus.iterator();
int i = 1;
while (iterator.hasNext()) {
Menu menu = iterator.next();
System.out.printf("%d. %s\n", i++, menu.getTitle());
}
System.out.printf("0. %s\n", "์ด์ ");
}
Iterator
๋ฅผ ์ฌ์ฉํ๋ฉด ์ ์ฒ๋ผ ์ฌ์ฉ๊ฐ๋ฅํ๋ค. ์๋ฃ๊ตฌ์กฐ๊ฐ ๋ณ๊ฒฝ๋๋๋ผ๋ Iterator
๋ฅผ ๊ตฌํํ ์๋ฃ๊ตฌ์กฐ์์๋ ๋์ผํ ๋ฐฉ์์ผ๋ก ๋ฐ์ดํฐ ์กฐํ๊ฐ ๊ฐ๋ฅํ๊ธฐ ๋๋ฌธ์ ์์ค๋ณ๊ฒฝ์ ํ ํ์๊ฐ ์๋ค.
๋ํ ๋ด๋ถ ๊ตฌ์กฐ๋ฅผ ๋
ธ์ถํ์ง ์๊ณ ์กฐํํ ์ ์๋ค๋ ์ฅ์ ๋ ์๋ค.
๊ฐ์ ํด์ผ ๋ ๋ถ๋ถ
์ดํฐ๋ ์ดํฐ ํจํด์ ์ ์ฉํด ์๋ฃ๊ตฌ์กฐ์ ์์กดํ์ง ์๊ณ ๋ฐ์ดํฐ๋ฅผ ์กฐํํ๋ ๋ฐฉ์์ผ๋ก ๋ณ๊ฒฝ์ ํ์ง๋ง LinkedListIterator
์ฝ๋๋ฅผ ๋ณด๋ฉด ๋ด๋ถ์์ ๊ฐ์ ์ฐพ๊ธฐ ์ํด ํญ์ ์ฒ์๋ถํฐ ์์ฐจ์ ์ผ๋ก ์ฐพ๋๋ค.
์ฝ๋์ ์ผ๊ด์ฑ์ ์ข์์ก์ง๋ง ๊ตณ์ด ํด๋์ค๋ก ๋ฐ๋ก ๋นผ๋์ ์ด์ ๊ฐ ์๊ณ , call stack ์ธก๋ฉด์์ ๋ณต์ก๋๋ง ๋ ๋์์ก๋ค. ์ด ๋ถ๋ถ์ ์ข ๋ ๊ฐ์ ํด๋ณด์.
static nested class ์ฌ์ฉ
์ฐ์ ์๋ฃ๊ตฌ์กฐ๋ง๋ค ๊ฐ์ ์ดํฐ๋ ์ดํฐ๋ฅผ ๊ตฌํํ ํด๋์ค๋ฅผ ๋ฐ๋ก ๋ง๋ค์ง ๋ง๊ณ , ์๋ฃ๊ตฌ์กฐ ํด๋์ค ๋ด๋ถ์ ์ดํฐ๋ ์ดํฐ ๊ตฌํํด๋์ค๋ฅผ ๋๊ณ ๊ด๋ฆฌํ๊ธฐ ์ฝ๋๋ก ๊ฐ์ ํด๋ณด์.
์ด์ฐจํผ ์๋ฃ๊ตฌ์กฐ๋ง๋ค Iterator
๋ฅผ ๊ตฌํํ ๊ฒ์ด๋ผ๋ฉด ํด๋น ์๋ฃ๊ตฌ์กฐ ์ฝ๋ ๊ฐ๊น์ด ๋ฐฐ์นํด ์ฝ๋๊ฐ์ ์์ง๋๋ฅผ ๋์ฌ ์ข ๋ ์ปดํฉํธํ๊ฒ ๊ด๋ฆฌํ์.
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
public class LinkedList<E> extends AbstractList<E> {
... //์๋ต
@Override
public Iterator<E> iterator() {
return new IteratorImpl<>(this);
}
/* static nested class */
private static class IteratorImpl<E> implements Iterator<E> {
LinkedList<E> list;
int cursor;
public IteratorImpl(LinkedList<E> list) {
this.list = list;
}
@Override
public boolean hasNext() {
return cursor >= 0 && cursor < list.size();
}
@Override
public E next() {
return list.get(cursor++);
}
}
...
}
LinkedList
ํด๋์ค ๋ด๋ถ์ static nested class ๋ก ์ดํฐ๋ ์ดํฐ ๊ตฌํํด๋์ค๋ฅผ ๋ง๋ค์๋ค. ํ์ฌ ๋ฉ์๋๋ ์ ์ (static)ํด๋์ค๊ฐ ๋ ์ ์๋ ์กฐ๊ฑด์ ๊ฐ์ถ๊ณ ์๊ธฐ ๋๋ฌธ์ static์ ๋ถ์ด๋ ๊ฒ์ด ๊ถ์ฅ๋๋ค.
static nested class๊ฐ ๋ ์ ์๋ ์กฐ๊ฑด ๋ฐ ํน์ง์ ๋ค์๊ณผ ๊ฐ๋ค.
- ์ธ๋ถ ํด๋์ค ์ธ์คํด์ค์ ๋ ๋ฆฝ์ : ์ ์ ์ค์ฒฉ ํด๋์ค๋ ์ธ๋ถ ํด๋์ค์ ์ธ์คํด์ค์ ๊ด๋ จ์ด ์๋ค. ์ธ๋ถ ํด๋์ค์ ์ธ์คํด์ค๋ฅผ ์์ฑํ์ง ์๊ณ ๋ ์ธ์คํด์คํ ํ ์ ์๋ค.
- ์ธ๋ถ ํด๋์ค ์ธ์คํด์ค์ ๋น์ ์ ๋ฉค๋ฒ์ ์ง์ ์ก์ธ์คํ ์ ์์: ์ ์ ์ค์ฒฉ ํด๋์ค๋ ์ธ๋ถ ํด๋์ค์ ์ ์ ๋ฉค๋ฒ๋ง ์ง์ ์ก์ธ์คํ ์ ์๋ค. ๋น์ ์ ๋ฉค๋ฒ์๋ ์ง์ ์ก์ธ์คํ ์ ์๋ค.
- ์ ์ ๋ฉค๋ฒ๋ฅผ ๊ฐ์ง ์ ์์: ์ ์ ์ค์ฒฉ ํด๋์ค๋ ์ ์ ํ๋ ๋ฐ ๋ฉ์๋๋ฅผ ๊ฐ์ง ์ ์๋ค.
- ๋ ๋ฆฝ์ ์ผ๋ก ์ธ์คํด์คํ ๊ฐ๋ฅ: ์ธ๋ถ ํด๋์ค์ ์ธ์คํด์ค๋ฅผ ์์ฑํ์ง ์๊ณ ๋ ์ ์ ์ค์ฒฉ ํด๋์ค์ ์ธ์คํด์ค๋ฅผ ์์ฑํ ์ ์๋ค.
์์์ ๊ตฌํํ ์ค์ฒฉํด๋์ค๋ ์ธ๋ถํด๋์ค์ ์ธ์คํด์ค ๋ฉค๋ฒ์ ์์ธ์คํ๊ณ ์์ง ์๋ค. ์ค์ฒฉํด๋์ค(๋ฉค๋ฒํด๋์ค) ๋ด๋ถ์์ ์์ฒด์ ์ผ๋ก ์ง์ LinkedList
๊ฐ์ฒด๋ฅผ ํตํ ์ํ๋ฅผ ํ๊ณ ์๋ค.
โ๏ธ ์ธ์คํด์ค ๋ฉค๋ฒ์ ์์ธ์คํ๊ณ ์์ง ์๋ค๋ ๋ง์ ํด๋น ํด๋์ค๋ ๋จ์ํ ํ๋ผ๋ฏธํฐ๋ก ๋ฐ์ ๊ฐ์ ๋ด๋ถ์ ์ผ๋ก ์ฒ๋ฆฌํ ๋ฟ์ด์ง, ์ธ๋ถ ์ธ์คํด์ค์ ํ๋๋ ๋ฉ์๋์ ์ ๊ทผํ๊ณ ์์ง ์๋ค๋ ๊ฒ์ ์๋ฏธํ๋ค. ์ฃผ๋ก ์ ํธ๋ฆฌํฐ ํจ์(Math ํด๋์ค ๋ฑ)๋ฅผ static class๋ก ์ฌ์ฉํ๋ค.
์ธ๋ถํด๋์ค์ ์ธ์คํด์ค ํ๋์ธ first๋ last์๋ ์ง์ ์ ๊ทผ์ด ๋ถ๊ฐ๋ฅํ๋ค. static nested class๋ด๋ถ์์ ์ธ๋ถํด๋์ค ์ธ์คํด์ค ์ฃผ์๋ฅผ ์ ์ฅํ์ง ์๊ธฐ ๋๋ฌธ์ด๋ค.
์๋ ์ฝ๋์ฒ๋ผ ์ธ๋ถํด๋์ค์ ์ธ์คํด์ค ํ๋ ์์ธ์ค๋ ๋ถ๊ฐ๋ฅํ๋ค. this
๋ฅผ ํตํด ์ธ๋ถ ํด๋์ค์ ์ธ์คํด์ค ์ฃผ์๋ฅผ ์์ฑ์ ํ๋ผ๋ฏธํฐ๋ก ๋๊ฒจ์ ์ฌ์ฉํ ๋ฟ์ด๋ค.
์ดํํฐ๋ธ ์๋ฐ p.146(์์ดํ 24) ์์ ์ ์ ๋ฉค๋ฒ ํด๋์ค์ ๋ํด ์๋์ ๊ฐ์ด ์์ ํ๊ณ ์๋ค.
์ ์ ๋ฉค๋ฒ ํด๋์ค์ ๋น์ ์ ๋ฉค๋ฒ ํด๋์ค์ ๊ตฌ๋ฌธ์ ์ฐจ์ด๋ ๋จ์ง static์ด ๋ถ์ด์๊ณ ์๊ณ ๋ฟ์ด์ง๋ง, ์๋ฏธ์ ์ฐจ์ด๋ ์์ธ๋ก ๊ฝค ํฌ๋ค. ๋น์ ์ ๋ฉค๋ฒ ํด๋์ค์ ์ธ์คํด์ค๋ ๋ฐ๊นฅ ํด๋์ค์ ์ธ์คํด์ค์ ์๋ฌต์ ์ผ๋ก ์ฐ๊ฒฐ๋๋ค. ๊ทธ๋์ ๋น์ ์ ๋ฉค๋ฒ ํด๋์ค์ ์ธ์คํด์ค ๋ฉ์๋์์ ์ ๊ทํ๋ this๋ฅผ ์ฌ์ฉํด ๋ฐ๊นฅ ์ธ์คํด์ค์ ๋ฉ์๋๋ฅผ ํธ์ถํ๊ฑฐ๋ ๋ฐ๊นฅ ์ธ์คํด์ค์ ์ฐธ์กฐ๋ฅผ ๊ฐ์ ธ์ฌ ์ ์๋ค. ์ ๊ทํ๋ this๋
ํด๋์ค๋ช .this
ํํ๋ก ๋ฐ๊นฅ ํด๋์ค์ ์ด๋ฆ์ ๋ช ์ํ๋ ์ฉ๋ฒ์ ๋งํ๋ค.[JLS, 15.8.4] ๋ฐ๋ผ์ ๊ฐ๋ ์ ์ค์ฒฉ ํด๋์ค์ ์ธ์คํด์ค๊ฐ ๋ฐ๊นฅ ์ธ์คํด์ค์ ๋ ๋ฆฝ์ ์ผ๋ก ์กด์ฌํ ์ ์๋ค๋ฉด ์ ์ ๋ฉค๋ฒ ํด๋์ค๋ก ๋ง๋ค์ด์ผ ํ๋ค. ๋น์ ์ ๋ฉค๋ฒ ํด๋์ค๋ ๋ฐ๊นฅ ์ธ์คํด์ค ์์ด๋ ์์ฑํ ์ ์๊ธฐ ๋๋ฌธ์ด๋ค.๋น์ ์ ๋ฉค๋ฒ ํด๋์ค์ ์ธ์คํด์ค์ ๋ฐ๊นฅ ์ธ์คํด์ค ์ฌ์ด์ ๊ด๊ณ๋ ๋ฉค๋ฒ ํด๋์ค๊ฐ ์ธ์คํด์คํ๋ ๋ ํ๋ฆฝ๋๋ฉฐ, ๋ ์ด์ ๋ณ๊ฒฝํ ์ ์๋ค. ์ด ๊ด๊ณ๋ ๋ฐ๊นฅ ํด๋์ค์ ์ธ์คํด์ค ๋ฉ์๋์์ ๋น์ ์ ๋ฉค๋ฒ ํด๋์ค์ ์์ฑ์๋ฅผ ํธ์ถํ ๋ ์๋์ผ๋ก ๋ง๋ค์ด์ง๋ ๊ฒ ๋ณดํต์ด์ง๋ง, ๋๋ฌผ๊ฒ๋ ์ง์
๋ฐ๊นฅ ์ธ์คํด์ค์ ํด๋์ค.new MemberClass(args)
๋ฅผ ํธ์ถํด ์๋์ผ๋ก ๋ง๋ค๊ธฐ๋ ํ๋ค. ์์ํ ์ ์๋ฏ, ์ด ๊ด๊ณ ์ ๋ณด๋ ๋น์ ์ ๋ฉค๋ฒ ํด๋์ค์ ์ธ์คํด์ค ์์ ๋ง๋ค์ด์ ธ ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ์ ์ฐจ์งํ๋ฉฐ, ์์ฑ ์๊ฐ๋ ๋ ๊ฑธ๋ฆฐ๋ค.
๋ฉค๋ฒ ํด๋์ค์์ ๋ฐ๊นฅ ์ธ์คํด์ค์ ์ ๊ทผํ ์ผ์ด ์๋ค๋ฉด ๋ฌด์กฐ๊ฑด static์ ๋ถ์ฌ์ ์ ์ ๋ฉค๋ฒ ํด๋์ค๋ก ๋ง๋ค์.
static์ ์๋ตํ๋ฉด ๋ฐ๊นฅ ์ธ์คํด์ค๋ก์ ์จ์ ์ธ๋ถ ์ฐธ์กฐ๋ฅผ ๊ฐ๊ฒ ๋๋ค. ์์๋ ์๊ธฐํ๋ฏ ์ด ์ฐธ์กฐ๋ฅผ ์ ์ฅํ๋ ค๋ฉด ์๊ฐ๊ณผ ๊ณต๊ฐ์ด ์๋น๋๋ค. ๋ ์ฌ๊ฐํ ๋ฌธ์ ๋ ๊ฐ๋น์ง ์ปฌ๋ ์ ์ด ๋ฐ๊นฅ ํด๋์ค์ ์ธ์คํด์ค๋ฅผ ์๊ฑฐํ์ง ๋ชปํ๋ ๋ฉ๋ชจ๋ฆฌ ๋์๊ฐ ์๊ธธ ์ ์๋ค๋ ์ ์ด๋ค(์์ดํ 7). ์ฐธ์กฐ๊ฐ ๋์ ๋ณด์ด์ง ์์ผ๋ ๋ฌธ์ ์ ์์ธ์ ์ฐพ๊ธฐ ์ด๋ ค์ ๋๋๋ก ์ฌ๊ฐํ ์ํฉ์ ์ด๋ํ๊ธฐ๋ ํ๋ค.
๋ง์ฝ ์ ํด๋์ค์ static
์ ๋ผ๊ณ ์์ฑ์๋ฅผ ์์ ๊ฒ ๋๋ฉด ์๋ฐ ์ปดํ์ผ๋ฌ๋ ํด๋์ค ๋ด๋ถ์ ์๋์ ๊ฐ์ ์ฝ๋๋ฅผ ์๋ฌต์ ์ผ๋ก ์ถ๊ฐํ๋ค.
1
2
3
4
5
6
7
8
9
10
11
private class IteratorImpl<E> implements Iterator<E> {
// ๋ฐ๊นฅ ๊ฐ์ฒด์ ์ฃผ์๋ฅผ ์ ์ฅํ ๋นํธ์ธ ํ๋
final LinkedList this;
// inner ๊ฐ์ฒด๋ฅผ ์์ฑํ ๋ ๋ฐ๊นฅ ๊ฐ์ฒด์ ์ฃผ์๋ฅผ ๋ฐ๋ ์์ฑ์
public IteratorImpl<E>(LinkedList p) {
this.this = p;
}
...
}
non-static class๋ ์ธ๋ถ ์ธ์คํด์ค ์ฃผ์๋ฅผ ํตํด์๋ง ์์ฑ ๊ฐ๋ฅํ๊ธฐ ๋๋ฌธ์ ์๋ฌต์ ์ผ๋ก this
๋ณ์๋ฅผ ๋ง๋ค์ด ์ธ์คํด์ค ๊ฐ์ ์ ์ฅํ๋ค. ์ฐธ์กฐ๋ฅผ ์ ์ฅํ๊ธฐ ์ํ ๊ณต๊ฐ๊ณผ ์๊ฐ์ด ์๋น๋๋ค.
non-static class๋ก ๋ง๋ค๋ฉด ์จ์ ์ธ๋ถ ์ฐธ์กฐ๋ฅผ ๊ฐ๊ฒ๋๋ค. ๋ฐ๊นฅ ํด๋์ค๋ฅผ ์ฐธ์กฐํ์ง ์๋ ๊ฒฝ์ฐ์ static ์ ๋ถ์ฌ๋ผ!
๊ทธ๋ฌ๋ ํ์ฌ ๊ฐ์ ํ๊ณ ์ ํ๋ ๋ชฉ์ ์ ์ธ๋ถ์ ์ฐธ์กฐ๋ฅผ ๋๊ณ ๋
๋ฆฝ์ ์ผ๋ก ๋์ํ๊ฒ ๋ง๋๋ ๊ฒ์ด ๋ชฉ์ ์ด ์๋๋ผ Iterator
์ ์ฝ๋๋ฅผ ์์ ํด ์์ง๋๋ฅผ ๋ํ๋ ๊ฒ์ด๋ค.
๋ํ ์ฒ์์ LinkedListIterator
ํด๋์ค๋ก ๋ฐ๋ก ๋ถ๋ฆฌ์์ผฐ๋ ์ฝ๋๋ฅผ LinkedList
์์ ๊ด๋ฆฌํ๊ธฐ ๋๋ฌธ์ ์ด๋ฅผ ํตํ ์ด์ ๋ ์ฑ๊ธธ ์ ์๋ค.
์ด๋ GRASP pattern
์ Information Expert
์กฐ๊ฑด์ ๋ง์กฑ์ํฌ ์ ์๋ ์ํฉ์ด๋ค.
โ๏ธ Information Expert: ์ญํ ์ ์ํํ ์ ์๋ ์ ๋ณด๋ฅผ ๊ฐ์ง๊ณ ์๋ ๊ฐ์ฒด์ ์ญํ ์ ๋ถ์ฌํ์. ๋จ์ํด ๋ณด์ด๋ ์ด ์์น์ ๊ฐ์ฒด์งํฅ์ ๊ธฐ๋ณธ ์๋ฆฌ ์ค์ ํ๋์ด๋ค. ๊ฐ์ฒด๋ ๋ฐ์ดํฐ์ ์ฒ๋ฆฌ๋ก์ง์ด ํจ๊ป ๋ฌถ์ฌ ์๋ ๊ฒ์ด๊ณ , ์์ ์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ถ๊ณ ์ ํ๋ฉด ์ค์ง ์๊ธฐ ์์ ์ ์ฒ๋ฆฌ ๋ก์ง์์๋ง ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ๊ณ , ์ธ๋ถ์๋ ๊ทธ ๊ธฐ๋ฅ(์ญํ )๋ง์ ์ ๊ณตํด์ผ ํ๊ธฐ ๋๋ฌธ์ด๋ค.
non-static class(inner class) ์ฌ์ฉ
static nested class ์์ ์ฐจ์ด์ ์ ์์ฑ์์ ํ๋ผ๋ฏธํฐ๊ฐ ์๋ค. ์ด๋ ํ๋ผ๋ฏธํฐ๋ก ๋ฐ์ดํฐ๋ฅผ ๋ฐ์ ๊ฐ๊ณต์ฒ๋ฆฌ ํ๋ ๋ฐฉ์์ด ์๋๋ผ,
inner class ๋ด๋ถ์ ์๋ฌต์ ์ผ๋ก ์์ฑ๋ this
๋ฅผ ํตํด ์ธ๋ถ ํด๋์ค์ ์ ๊ทผํ๊ฒ ๋ค๋ ์๋ฏธ๋ค.
inner class๋ฅผ ์ฌ์ฉํ๋ฉด ์ธ๋ถํด๋์ค์ ๋ณ์๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
Iterator
ํธ์ถ์ ํตํด ์ํ๋ฅผ ํ ๋๋ง๋ค ๋ฉค๋ฒํด๋์ค ์์ฑ์๋ก ์ธ์คํด์ค๋ฅผ ๋ฐ์์ ์ฒ๋ฆฌํ๋ ๊ฒ์ด ์๋๋ผ, ์ธ๋ถ ์ธ์คํด์ค์ ์ฃผ์์ ์ง์ ์ ๊ทผํด ํด๋น ํ๋์ ๋ฐ์ดํฐ๋ฅผ ์ด์ฉํด ์์
ํ๊ฒ ๋๋ค.
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
public class LinkedList<E> extends AbstractList<E> {
... //์๋ต
@Override
public Iterator<E> iterator() {
return new IteratorImpl<>();
}
/* non-static class */
private class IteratorImpl<E> implements Iterator<E> {
Node<E> cursor;
// ์์ฑ์ ์ฝ๋๋ฅผ ํตํด ์ธ๋ถ ํด๋์ค ๋ณ์๋ฅผ ์ฐธ์กฐํ๋ค.
public IteratorImpl() {
this.cursor = (Node<E>) LinkedList.this.first;
}
@Override
public boolean hasNext() {
return cursor != null;
}
@Override
public E next() {
E value = cursor.value;
cursor = cursor.next;
return value;
}
}
...
}
์ค์ ๋ก java.util.LinkedList
์์ ๋ด๋ถํด๋์ค๋ก Iterator
๋ฅผ ๊ตฌํํ๊ณ ์๋ค.
java.util.LinkedList์ Iterator
์ต๋ช ํด๋์ค(anonymous class) ์ฌ์ฉ
์ต๋ช
ํด๋์ค๋ ํด๋์ค์ ์ด๋ฆ์ด ์กด์ฌํ์ง ์๋ ํด๋์ค๋ค. ์๋ ์ฝ๋์ฒ๋ผ ์์ฑ๊ณผ ๊ตฌํ๋ถ๋ถ์ ์กด์ฌํ์ง๋ง class
๋ผ๋ ํค์๋๋ ์๊ณ ํด๋์ค์ ์ด๋ฆ๋ ์๋ค.
์ฐ์ด๋ ์์ ์ ์ ์ธ๊ณผ ๋์์ ์ธ์คํด์ค๊ฐ ๋ง๋ค์ด์ง๋ค. ๋ฐ๋ผ์ ์ต๋ช ํด๋์ค๋ ์ฌ์ฌ์ฉ์ด ๋ถ๊ฐ๋ฅํ๋ค.
์ต๋ช ํด๋์ค๋ ๊ฐ์ฒด๋ก์ ๋ค๋ฃจ๊ฒ ๋ค๋ ์๋ฏธ๋ณด๋ค๋ 1ํ์ฑ ์ด๊ฑฐ๋ ์งง์ ๊ตฌํ๋ถ๋ฅผ ๊ฐ์ง ๊ฐ๋จํ ํด๋์ค์ ๊ฒฝ์ฐ ๊ตณ์ด ํด๋์ค๋ก ์ ์ํ ํ์๊ฐ ์๋ค๋ ๊ฒ์ ์ข ๋ ์๋ฏธ๊ฐ ์๋ค.
์ ์ธ๊ณผ ๊ตฌํ์ ๋์์ ํ๊ธฐ๋๋ฌธ์ ์ธํฐํ์ด์ค ๋ํ ์ต๋ช ํด๋์ค๋ก ๋ฐ๋ก ๊ตฌํํด์ ์ธ ์ ์๋ค. ๊ทธ๋ฆฌ๊ณ ๋ชจ์์ ์ ๋ณด๋ฉด ๊ฐ์ฒด๋ฅผ ์์ฑํด ๋ฐ๋ก ๋ฆฌํดํ๋ค. ์ด๋ ์ดํํฐ๋ธ ์๋ฐ์์ ๋งํ๋ ์ ์ ํฉํ ๋ฆฌ ๋ฉ์๋ ๊ตฌํ์ ์ฃผ๋ก ์ฌ์ฉ๋๋ค.(ํฉํ ๋ฆฌ ๋ฉ์๋ ํจํด์ด ์๋๋ค.)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
...
@Override
public Iterator<E> iterator() {
return new Iterator<>() { // ์ต๋ช
ํด๋์ค
Node<E> cursor = LinkedList.this.first;
@Override
public boolean hasNext() {
return cursor != null;
}
@Override
public E next() {
E value = cursor.value;
cursor = cursor.next;
return value;
}
};
}
์์ค์ฝ๋
์ ๋ฆฌ
์ดํํฐ๋ธ ์๋ฐ์์ ๋ฉค๋ฒ ํด๋์ค์ ๋ํด ์๋์ ๊ฐ์ด ์ ๋ฆฌํ๊ณ ์๋ค.
๋ฉ์๋ ๋ฐ์์๋ ์ฌ์ฉํด์ผ ํ๊ฑฐ๋ ๋ฉ์๋ ์์ ์ ์ํ๊ธฐ์ ๋๋ฌด ๊ธธ๋ค๋ฉด
๋ฉค๋ฒ ํด๋์ค
๋ก ๋ง๋ ๋ค.
- ๋ฉค๋ฒ ํด๋์ค์ ์ธ์คํด์ค๊ฐ ๋ฐ๊นฅ ์ธ์คํด์ค๋ฅผ ์ฐธ์กฐํ๋ค๋ฉด ๐ non-static class
- ๋ฉค๋ฒ ํด๋์ค์ ์ธ์คํด์ค๊ฐ ๋ฐ๊นฅ ์ธ์คํด์ค๋ฅผ ์ฐธ์กฐํ์ง ์๋๋ค๋ฉด ๐ static nested class
- ๋ฉค๋ฒ ํด๋์ค๊ฐ ํ ๋ฉ์๋ ์์์๋ง ์ฐ์ด๋ฉด์ ๊ทธ ์ธ์คํด์ค๋ฅผ ์์ฑํ๋ ์ง์ ์ด ๋จ ํ ๊ณณ์ด๊ณ ํด๋น ํ์ ์ผ๋ก ์ฐ๊ธฐ์ ์ ํฉํ ํด๋์ค๋ ์ธํฐํ์ด์ค๊ฐ ์ด๋ฏธ ์๋ค๋ฉด ๐ anonymous class
reference
- ํ๋น์ถํ๋คํธ์ํฌ
- ์ดํํฐ๋ธ ์๋ฐ 3ํ
๋๊ธ๋จ๊ธฐ๊ธฐ