๐ ๋ฐ๋ณต์(Iterator) ํจํด - ์๋ฒฝ ๋ง์คํฐํ๊ธฐ
Iterator Pattern
๋ฐ๋ณต์(Iterator) ํจํด์ ์ผ๋ จ์ ๋ฐ์ดํฐ ์งํฉ์ ๋ํ์ฌ ์์ฐจ์ ์ธ ์ ๊ทผ(์ํ)์ ์ง์ํ๋ ํจํด์ด๋ค.
๋ฐ์ดํฐ ์งํฉ์ด๋ ๊ฐ์ฒด๋ค์ ๊ทธ๋ฃน์ผ๋ก ๋ฌถ์ด ์๋ฃ์ ๊ตฌ์กฐ๋ฅผ ์ทจํ๋ ์ปฌ๋ ์ ์ ๋งํ๋ค. ๋ํ์ ์ธ ์ปฌ๋ ์ ์ผ๋ก ํ๋ฒ์ฏค์ ๋ค์ด๋ณธ ๋ฆฌ์คํธ๋ ํธ๋ฆฌ, ๊ทธ๋ํ, ํ ์ด๋ธ ..๋ฑ์ด ์๋ค.
๋ณดํต ๋ฐฐ์ด์ด๋ ๋ฆฌ์คํธ ๊ฐ์ ๊ฒฝ์ฐ ์์๊ฐ ์ฐ์์ ์ธ ๋ฐ์ดํฐ ์งํฉ์ด๊ธฐ ๋๋ฌธ์ ๊ฐ๋จํ for๋ฌธ์ ํตํด ์ํํ ์ ์๋ค. ๊ทธ๋ฌ๋ ํด์, ํธ๋ฆฌ์ ๊ฐ์ ์ปฌ๋ ์ ์ ๋ฐ์ดํฐ ์ ์ฅ ์์๊ฐ ์ ํด์ง์ง ์๊ณ ์ ์ฌ๋๊ธฐ ๋๋ฌธ์, ๊ฐ ์์๋ค์ ์ด๋ค ๊ธฐ์ค์ผ๋ก ์ ๊ทผํด์ผ ํ ์ง ์ ๋งคํด์ง๋ค.
์๋ฅผ๋ค์ด ์๋์ ๊ฐ์ด ํธ๋ฆฌ ๊ตฌ์กฐ๊ฐ ์๋ค๋ฉด ์ด๋ค ์ํฉ์์ ๊น์ด(์ธ๋ก)๋ฅผ ์ฐ์ ์ผ๋ก ์ํ ํด์ผ ํ ์๋ ์๊ณ , ๋๋น(๊ฐ๋ก)๋ฅผ ์ฐ์ ์ผ๋ก ์ํํ ์๋ ์๊ธฐ ๋๋ฌธ์ด๋ค.
์ด์ฒ๋ผ ๋ณต์กํ๊ฒ ์ฝํ์๋ ์๋ฃ ์ปฌ๋ ์ ๋ค์ ์ํํ๋ ์๊ณ ๋ฆฌ์ฆ ์ ๋ต์ ์ ์ํ๋ ๊ฒ์ ์ดํฐ๋ ์ดํฐ ํจํด์ด๋ผ๊ณ ํ๋ค.
์ปฌ๋ ์ ๊ฐ์ฒด ์์ ๋ค์ด์๋ ๋ชจ๋ ์์๋ค์ ๋ํ ์ ๊ทผ ๋ฐฉ์์ด ๊ณตํตํ ๋์ด ์๋ค๋ฉด ์ด๋ค ์ข ๋ฅ์ ์ปฌ๋ ์ ์์๋ ์ดํฐ๋ ์ดํฐ๋ง ๋ฝ์๋ด๋ฉด ์ฌ๋ฌ ์ ๋ต์ผ๋ก ์ํ๊ฐ ๊ฐ๋ฅํด ๋ณด๋ค ๋คํ(ๅคๅฝข) ์ ์ธ ์ฝ๋๋ฅผ ์ค๊ณํ ์ ์๊ฒ ๋๋ค.
์๋ฐ์ ์ปฌ๋ ์ ํ๋ ์์ํฌ(JCF)์์ ๊ฐ์ข ์ปฌ๋ ์ ์ ๋ฌด๋ฆฌ์์ด ์ํํ ์ ์๋ ๊ฒ๋ ๋ด๋ถ์ ๋ฏธ๋ฆฌ ์ดํฐ๋ ์ดํฐ ํจํด์ด ์ ์ฉ๋์ด ์๊ธฐ ๋๋ฌธ์ด๋ค.
์ด๋ฐ์๋ ์ดํฐ๋ ์ดํฐ ํจํด์ ๋ณ๋์ ์ดํฐ๋ ์ดํฐ ๊ฐ์ฒด๋ฅผ ๋ฐํ ๋ฐ์ ์ด๋ฅผ ์ด์ฉํด ์ํํ๊ธฐ ๋๋ฌธ์, ์งํฉ์ฒด์ ๋ด๋ถ ๊ตฌ์กฐ๋ฅผ ๋ ธ์ถํ์ง ์๊ณ ์ํ ํ ์ ์๋ค๋ ์ฅ์ ๋ ์๋ค.
์ดํฐ๋ ์ดํฐ ํจํด ๊ตฌ์กฐ
- Aggregate (์ธํฐํ์ด์ค) : ConcreateIterator ๊ฐ์ฒด๋ฅผ ๋ฐํํ๋ ์ธํฐํ์ด์ค๋ฅผ ์ ๊ณตํ๋ค.
- iterator() : ConcreateIterator ๊ฐ์ฒด๋ฅผ ๋ง๋๋ ํฉํ ๋ฆฌ ๋ฉ์๋
- ConcreateAggregate (ํด๋์ค) : ์ฌ๋ฌ ์์๋ค์ด ์ด๋ฃจ์ด์ ธ ์๋ ๋ฐ์ดํฐ ์งํฉ์ฒด
- Iterator (์ธํฐํ์ด์ค) : ์งํฉ์ฒด ๋ด์ ์์๋ค์ ์์๋๋ก ๊ฒ์ํ๊ธฐ ์ํ ์ธํฐํ์ด์ค๋ฅผ ์ ๊ณตํ๋ค.
- hasNext() : ์ํํ ๋ค์ ์์๊ฐ ์๋์ง ํ์ธ (true / false)
- next() : ์์๋ฅผ ๋ฐํํ๊ณ ๋ค์ ์์๋ฅผ ๋ฐํํ ์ค๋น๋ฅผ ํ๊ธฐ ์ํด ์ปค์๋ฅผ ์ด๋์ํด
- ConcreateIterator (ํด๋์ค) : ๋ฐ๋ณต์ ๊ฐ์ฒด
- ConcreateAggregate๊ฐ ๊ตฌํํ ๋ฉ์๋๋ก๋ถํฐ ์์ฑ๋๋ฉฐ, ConcreateAggregate ์ ์ปฌ๋ ์ ์ ์ฐธ์กฐํ์ฌ ์ํํ๋ค.
- ์ด๋ค ์ ๋ต์ผ๋ก ์ํํ ์ง์ ๋ํ ๋ก์ง์ ๊ตฌ์ฒดํ ํ๋ค.
์ดํฐ๋ ์ดํฐ ํจํด ํ๋ฆ
ํด๋์ค ๊ตฌ์ฑ
// ์งํฉ์ฒด ๊ฐ์ฒด (์ปฌ๋ ์
)
interface Aggregate {
Iterator iterator();
}
class ConcreteAggregate implements Aggregate {
Object[] arr; // ๋ฐ์ดํฐ ์งํฉ (์ปฌ๋ ์
)
int index = 0;
public ConcreteAggregate(int size) {
this.arr = new Object[size];
}
public void add(Object o) {
if(index < arr.length) {
arr[index] = o;
index++;
}
}
// ๋ด๋ถ ์ปฌ๋ ์
์ ์ธ์๋ก ๋ฃ์ด ์ดํฐ๋ ์ดํฐ ๊ตฌํ์ฒด๋ฅผ ํด๋ผ์ด์ธํธ์ ๋ฐํ
@Override
public Iterator iterator() {
return new ConcreteIterator(arr);
}
}
// ๋ฐ๋ณต์ฒด ๊ฐ์ฒด
interface Iterator {
boolean hasNext();
Object next();
}
class ConcreteIterator implements Iterator {
Object[] arr;
private int nextIndex = 0; // ์ปค์ (for๋ฌธ์ i ๋ณ์ ์ญํ )
// ์์ฑ์๋ก ์ํํ ์ปฌ๋ ์
์ ๋ฐ์ ํ๋์ ์ฐธ์กฐ ์ํด
public ConcreteIterator(Object[] arr) {
this.arr = arr;
}
// ์ํํ ๋ค์ ์์๊ฐ ์๋์ง true / false
@Override
public boolean hasNext() {
return nextIndex < arr.length;
}
// ๋ค์ ์์๋ฅผ ๋ฐํํ๊ณ ์ปค์๋ฅผ ์ฆ๊ฐ์์ผ ๋ค์ ์์๋ฅผ ๋ฐ๋ผ๋ณด๋๋ก ํ๋ค.
@Override
public Object next() {
return arr[nextIndex++];
}
}
ํด๋์ค ํ๋ฆ
public static void main(String[] args) {
// 1. ์งํฉ์ฒด ์์ฑ
ConcreteAggregate aggregate = new ConcreteAggregate(5);
aggregate.add(1);
aggregate.add(2);
aggregate.add(3);
aggregate.add(4);
aggregate.add(5);
// 2. ์งํฉ์ฒด์์ ์ดํฐ๋ ์ดํฐ ๊ฐ์ฒด ๋ฐํ
Iterator iter = aggregate.iterator();
// 3. ์ดํฐ๋ ์ดํฐ ๋ด๋ถ ์ปค์๋ฅผ ํตํด ์ํ
while(iter.hasNext()) {
System.out.printf("%s → ", iter.next());
}
}
์์ ์์ ์์ ๊ตฌํ์ ๊ฐ๋จํ ํ๊ธฐ ์ํด ์งํฉ ๊ฐ์ฒด์ ๋ด๋ถ ์ปฌ๋ ์ ์ ๋ฐฐ์ด๋ก ํํํ์ง๋ง, ๋ฐฐ์ด ๋ฟ๋ง ์๋๋ผ ์ฌ๋ฌ ๋ณต์กํ ์ปฌ๋ ์ ์ผ๋ก๋ ์ดํฐ๋ ์ดํฐ ๊ตฌํ์ด ๊ฐ๋ฅํ๋ค.
์ดํฐ๋ ์ดํฐ ํจํด ํน์ง
ํจํด ์ฌ์ฉ ์๊ธฐ
- ์ปฌ๋ ์ ์ ์๊ด์์ด ๊ฐ์ฒด ์ ๊ทผ ์ํ ๋ฐฉ์์ ํต์ผํ๊ณ ์ ํ ๋
- ์ปฌ๋ ์ ์ ์ํํ๋ ๋ค์ํ ๋ฐฉ๋ฒ์ ์ง์ํ๊ณ ์ถ์ ๋
- ์ปฌ๋ ์ ์ ๋ณต์กํ ๋ด๋ถ ๊ตฌ์กฐ๋ฅผ ํด๋ผ์ด์ธํธ๋ก ๋ถํฐ ์จ๊ธฐ๊ณ ์ถ์ ๊ฒฝ์ฐ (ํธ์ + ๋ณด์)
- ๋ฐ์ดํฐ ์ ์ฅ ์ปฌ๋ ์
์ข
๋ฅ๊ฐ ๋ณ๊ฒฝ ๊ฐ๋ฅ์ฑ์ด ์์ ๋
- ํด๋ผ์ด์ธํธ๊ฐ ์งํฉ ๊ฐ์ฒด ๋ด๋ถ ํํ ๋ฐฉ์์ ์๊ณ ์๋ค๋ฉด, ํํ ๋ฐฉ์์ด ๋ฌ๋ผ์ง๋ฉด ํด๋ผ์ด์ธํธ ์ฝ๋๋ ๋ณ๊ฒฝ๋์ด์ผ ํ๋ ๋ฌธ์ ๊ฐ ์๊ธด๋ค.
ํจํด ์ฅ์
- ์ผ๊ด๋ ์ดํฐ๋ ์ดํฐ ์ธํฐํ์ด์ค๋ฅผ ์ฌ์ฉํด ์ฌ๋ฌ ํํ์ ์ปฌ๋ ์ ์ ๋ํด ๋์ผํ ์ํ ๋ฐฉ๋ฒ์ ์ ๊ณตํ๋ค.
- ์ปฌ๋ ์ ์ ๋ด๋ถ ๊ตฌ์กฐ ๋ฐ ์ํ ๋ฐฉ์์ ์์ง ์์๋ ๋๋ค.
- ์งํฉ์ฒด์ ๊ตฌํ๊ณผ ์ ๊ทผํ๋ ์ฒ๋ฆฌ ๋ถ๋ถ์ ๋ฐ๋ณต์ ๊ฐ์ฒด๋ก ๋ถ๋ฆฌํด ๊ฒฐํฉ๋๋ฅผ ์ค ์ผ ์ ์๋ค.
- Client์์ iterator๋ก ์ ๊ทผํ๊ธฐ ๋๋ฌธ์ ConcreteAggregate ๋ด์ ์์ ์ฌํญ์ด ์๊ฒจ๋ iterator์ ๋ฌธ์ ๊ฐ ์๋ค๋ฉด ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ง ์๋๋ค.
- ์ํ ์๊ณ ๋ฆฌ์ฆ์ ๋ณ๋์ ๋ฐ๋ณต์ ๊ฐ์ฒด์ ์ถ์ถํ์ฌ ๊ฐ ํด๋์ค์ ์ฑ ์์ ๋ถ๋ฆฌํ์ฌ ๋จ์ผ ์ฑ ์ ์์น(SRP)๋ฅผ ์ค์ํ๋ค.
- ๋ฐ์ดํฐ ์ ์ฅ ์ปฌ๋ ์ ์ข ๋ฅ๊ฐ ๋ณ๊ฒฝ๋์ด๋ ํด๋ผ์ด์ธํธ ๊ตฌํ ์ฝ๋๋ ์์๋์ง ์์ ์์ ์๋ ๋ซํ ์์ด ๊ฐ๋ฐฉ ํ์ ์์น(OCP)๋ฅผ ์ค์ํ๋ค.
ํจํด ๋จ์
- ํด๋์ค๊ฐ ๋์ด๋๊ณ ๋ณต์ก๋๊ฐ ์ฆ๊ฐํ๋ค.
- ๋ง์ผ ์ฑ์ด ๊ฐ๋จํ ์ปฌ๋ ์ ์์๋ง ์๋ํ๋ ๊ฒฝ์ฐ ํจํด์ ์ ์ฉํ๋ ๊ฒ์ ๋ณต์ก๋๋ง ์ฆ๊ฐํ ์ ์๋ค.
- ์ดํฐ๋ ์ดํฐ ๊ฐ์ฒด๋ฅผ ๋ง๋๋ ๊ฒ์ด ์ ์ฉํ ์ํฉ์ธ์ง ํ๋จํ ํ์๊ฐ ์๋ค.
- ๊ตฌํ ๋ฐฉ๋ฒ์ ๋ฐ๋ผ ์บก์ํ๋ฅผ ์๋ฐฐํ ์ ์๋ค.
์์ ๋ฅผ ํตํด ์์๋ณด๋ Iterator ํจํด
์ดํฐ๋ ์ดํฐ๋ก ์ํ ์ ๋ต์ ๋๋๊ธฐ
ํด๋ผ์ด์ธํธ ์๊ตฌ์ฌํญ์ ๋ค์๊ณผ ๊ฐ๋ค. ๊ฒ์ํ์ ๊ธ์ ์ฌ๋ฆด๊ฑด๋ฐ, ๊ฒ์๊ธ์ ์ต๊ทผ๊ธ, ์์ฑ์์ผ๋ก ์ ๋ ฌํด์ ๋์ด ํ ์ ์๊ฒ ํด๋ฌ๋ผ๊ณ ํ๋ค. ์ฆ, ๋๊ฐ์ง ์ ๋ ฌ ์ ๋ต์ ๊ตฌํํด์ผ ๋๋ ๊ฒ์ด๋ค.
ํด๋ฆฐํ์ง ์์ ๋ฌธ์ ์ ์ฝ๋ โ
๋ค์์ ๊ฒ์๊ธ(Post)๊ณผ ๊ฒ์ํ(Borad)๋ฅผ ํํํ ์ธ์คํด์ค์ด๋ค.
๊ฒ์๊ธ์๋ ๊ฒ์๊ธ ์ ๋ชฉ title๊ณผ ๊ฒ์๊ธ ๋ฐํ ๋ ์ง ํ๋๊ฐ ์๋ค. (์ฝ๋ ๊ฐ๋ตํ๋ฅผ ์ํด ๊ฒ์๊ธ ๋ด์ฉ์ ์๋ตํ์๋ค)
// ๊ฒ์๊ธ
class Post {
String title; // ๊ฒ์๊ธ ์ ๋ชฉ
LocalDate date; // ๊ฒ์๊ธ ๋ฐํ์ผ
public Post(String title, LocalDate date) {
this.title = title;
this.date = date;
}
}
// ๊ฒ์ํ
class Board {
// ๊ฒ์๊ธ์ ๋ฆฌ์คํธ ์งํฉ ๊ฐ์ฒด๋ก ์ ์ฅ ๊ด๋ฆฌ
List<Post> posts = new ArrayList<>();
public void addPost(String title, LocalDate date) {
this.posts.add(new Post(title, date));
}
public List<Post> getPosts() {
return posts;
}
}
public static void main(String[] args) {
// 1. ๊ฒ์ํ ์์ฑ
Board board = new Board();
// 2. ๊ฒ์ํ์ ๊ฒ์๊ธ์ ํฌ์คํ
board.addPost("๋์์ธ ํจํด ๊ฐ์ ๋ฆฌ๋ทฐ", LocalDate.of(2020, 8, 30));
board.addPost("๊ฒ์ ํ์ค๋ถ", LocalDate.of(2020, 2, 6));
board.addPost("์ด๊ฑฐ ์ด๋ป๊ฒ ํ๋์?", LocalDate.of(2020, 6, 1));
board.addPost("์ด๊ฑฐ ์ด๋ป๊ฒ ํ๋์?", LocalDate.of(2021, 12, 22));
List<Post> posts = board.getPosts();
// 3. ๊ฒ์๊ธ ๋ฐํ ์์๋๋ก ์กฐํํ๊ธฐ
for (int i = 0; i < posts.size(); i++) {
Post post = posts.get(i);
System.out.println(post.title + " / " + post.date);
}
// 4. ๊ฒ์๊ธ ๋ ์ง๋ณ๋ก ์กฐํํ๊ธฐ
Collections.sort(posts, (p1, p2) -> p1.date.compareTo(p2.date)); // ์งํฉ์ฒด๋ฅผ ๋ ์ง๋ณ๋ก ์ ๋ ฌ
for (int i = 0; i < posts.size(); i++) {
Post post = posts.get(i);
System.out.println(post.title + " / " + post.date);
}
}
์ผ๋ฐ์ ์ผ๋ก for๋ฌธ์ ๋๋ ค ์งํฉ์ฒด์ ์์๋ค์ ์ํํ์๋ค. ๊ทธ๋ฌ๋ ์ด๋ฌํ ๊ตฌ์ฑ ๋ฐฉ์์ Board์ ๋ค์ด๊ฐ Post๋ฅผ ์ํํ ๋, Board๊ฐ ์ด๋ ํ ๊ตฌ์กฐ๋ก ์ด๋ฃจ์ด์ ธ ์๋์ง๋ฅผ ํด๋ผ์ด์ธํธ์ ๋ ธ์ถ๋๋ค. ๋ฐ๋ผ์ ์ด๋ฅผ ๋ณด๋ค ๊ฐ์ฒด ์งํฅ์ ์ผ๋ก ๊ตฌ์ฑํ๊ธฐ ์ํด ์ดํฐ๋ ์ดํฐ ํจํด์ ์ ์ฉํด๋ณด์.
์ดํฐ๋ ์ดํฐ ํจํด์ ์ ์ฉํ ์ฝ๋ โ๏ธ
์์์ ์ดํฐ๋ ์ดํฐ ์ธํฐํ์ด์ค๋ฅผ ์ง์ ๋ง๋ค์ด ์ผ์ง๋ง, ์๋ฐ์์ ์ด๋ฏธ ์ดํฐ๋ ์ดํฐ ์ธํฐํ์ด์ค๋ฅผ ์ง์ํ๋ค. ์๋ฐ์ ๋ด๋ถ ์ดํฐ๋ ์ดํฐ๋ฅผ ์ฌํ์ฉํด์ ๋ฉ์๋ ์์์ ํตํด ์ฝ๋๋ฅผ ๊ฐ๋จํ๊ฒ ๊ตฌํํ ์๋ ์๋ค.
์ํ ์ ๋ต์ผ๋ก๋ ๋ฆฌ์คํธ ์ ์ฅ ์์๋๋ก ์กฐํ์ ๋ ์ง ์์๋๋ก ์กฐํ ๋๊ฐ์ง๊ฐ ์กด์ฌํ๋ค. ๋ฐ๋ผ์ ์ด์ ๋ํ ์ดํฐ๋ ์ดํฐ ํด๋์ค ์ญ์ ๋๊ฐ์ง ์์ฑํด์ฃผ๋ฉด ๋๋ค.
- ListPostIterator : ์ ์ฅ ์์ ์ดํฐ๋ ์ดํฐ
- DatePostIterator : ๋ ์ง ์์ ์ดํฐ๋ ์ดํฐ
๊ทธ๋ฆฌ๊ณ ListPostIterator ์ DatePostIterator ๊ฐ์ฒด๋ฅผ ๋ฐํํ๋ ํฉํ ๋ฆฌ ๋ฉ์๋๋ฅผ Board ํด๋์ค์ ์ถ๊ฐ๋ง ํด์ฃผ๋ฉด ์์ฑ ๋๋ค.
// ์ ์ฅ ์์ ์ดํฐ๋ ์ดํฐ
class ListPostIterator implements Iterator<Post> {
private Iterator<Post> itr;
public ListPostIterator(List<Post> posts) {
this.itr = posts.iterator();
}
@Override
public boolean hasNext() {
return this.itr.hasNext(); // ์๋ฐ ๋ด๋ถ ์ดํฐ๋ ์ดํฐ์ ์์ํด ๋ฒ๋ฆผ
}
@Override
public Post next() {
return this.itr.next(); // ์๋ฐ ๋ด๋ถ ์ดํฐ๋ ์ดํฐ์ ์์ํด ๋ฒ๋ฆผ
}
}
// ๋ ์ง ์์ ์ดํฐ๋ ์ดํฐ
class DatePostIterator implements Iterator<Post> {
private Iterator<Post> itr;
public DatePostIterator(List<Post> posts) {
// ์ต์ ๊ธ ๋ชฉ๋ก์ด ๋จผ์ ์ค๋๋ก ์ ๋ ฌ
Collections.sort(posts, (p1, p2) -> p1.date.compareTo(p2.date));
this.itr = posts.iterator();
}
@Override
public boolean hasNext() {
return this.itr.hasNext(); // ์๋ฐ ๋ด๋ถ ์ดํฐ๋ ์ดํฐ์ ์์ํด ๋ฒ๋ฆผ
}
@Override
public Post next() {
return this.itr.next(); // ์๋ฐ ๋ด๋ถ ์ดํฐ๋ ์ดํฐ์ ์์ํด ๋ฒ๋ฆผ
}
}
// ๊ฒ์ํ
class Board {
// ๊ฒ์๊ธ์ ๋ฆฌ์คํธ ์งํฉ ๊ฐ์ฒด๋ก ์ ์ฅ ๊ด๋ฆฌ
List<Post> posts = new ArrayList<>();
public void addPost(String title, LocalDate date) {
this.posts.add(new Post(title, date));
}
public List<Post> getPosts() {
return posts;
}
// ListPostIterator ์ดํฐ๋ ์ดํฐ ๊ฐ์ฒด ๋ฐํ
public Iterator<Post> getListPostIterator() {
return new ListPostIterator(posts);
}
// DatePostIterator ์ดํฐ๋ ์ดํฐ ๊ฐ์ฒด ๋ฐํ
public Iterator<Post> getDatePostIterator() {
return new DatePostIterator(posts);
}
}
public static void main(String[] args) {
// 1. ๊ฒ์ํ ์์ฑ
Board board = new Board();
// 2. ๊ฒ์ํ์ ๊ฒ์๊ธ์ ํฌ์คํ
board.addPost("๋์์ธ ํจํด ๊ฐ์ ๋ฆฌ๋ทฐ", LocalDate.of(2020, 8, 30));
board.addPost("๊ฒ์ ํ์ค๋ถ", LocalDate.of(2020, 2, 6));
board.addPost("์ด๊ฑฐ ์ด๋ป๊ฒ ํ๋์?", LocalDate.of(2020, 6, 1));
board.addPost("์ด๊ฑฐ ์ด๋ป๊ฒ ํ๋์?", LocalDate.of(2021, 12, 22));
// ๊ฒ์๊ธ ๋ฐํ ์์๋๋ก ์กฐํํ๊ธฐ
print(board.getListPostIterator());
// ๊ฒ์๊ธ ๋ ์ง๋ณ๋ก ์กฐํํ๊ธฐ
print(board.getDatePostIterator());
}
public static void print(Iterator<Post> iterator) {
Iterator<Post> itr = iterator;
while(itr.hasNext()) {
Post post = itr.next();
System.out.println(post.title + " / " + post.date);
}
}
์ด์ ํด๋ผ์ด์ธํธ๋ ๊ฒ์๊ธ์ ์ํํ ๋ Board ๋ด๋ถ๊ฐ ์ด๋ค ์งํฉ์ฒด๋ก ๊ตฌํ(Array, List, Tree, Queue ..๋ฑ) ๋์ด ์๋์ง ์ ์ ์๊ฒ ๊ฐ์ถ๊ณ ์ ํ ์ ๊ฒฝ ์ธ ํ์๊ฐ ์๊ฒ ๋์๋ค. ๊ทธ๋ฆฌ๊ณ ์ํ ์ ๋ต์ ๊ฐ ๊ฐ์ฒด๋ก ๋๋์ผ๋ก์จ ๋์ ๋ฐ๋ผ ์ ์ ํ ์ดํฐ๋ ์ดํฐ ๊ฐ์ฒด๋ง ๋ฐ์ผ๋ฉด ๋๊ฐ์ ์ดํฐ๋ ์ดํฐ ์ํ ์ฝ๋๋ก ๋ค์ํ ์ํ ์ ๋ต์ ๊ตฌ์ฌํ ์ ์๊ฒ ๋์๋ค.
์งํฉ์ฒด ๊ตฌํ์ ์๊ด ์์ด ์ํ๋ฅผ ํํ โ๏ธ
Iterator๋ฅผ ์ฌ์ฉํ๋ ๋๋ค๋ฅธ ์ด์ ๋ ์ดํฐ๋ ์ดํฐ๋ฅผ ์ฌ์ฉํจ์ผ๋ก์จ ์งํฉ์ฒด ๊ตฌํ๊ณผ ๋ถ๋ฆฌํ ์ ์๊ธฐ ๋๋ฌธ์ด๋ค.
Iterator<Post> itr = iterator;
while(itr.hasNext()) {
Post post = itr.next();
System.out.println(post.title + " / " + post.date);
}
์ดํฐ๋ ์ดํฐ ๊ฐ์ฒด๋ฅผ ๋ฐํํ๋ฉด ์ปฌ๋ ์
์ ์ํํ ๋ hasNext() ์ next() ๋ผ๋ Iterator์ ๋ฉ์๋๋ง์ ์ด์ฉํ๊ธฐ ๋๋ฌธ์, ์งํฉ์ฒด์ธ Board์ ๋ด๋ถ ๊ตฌ์ฑ์ ๊ฐ์ถ์ ์๊ฒ ๋๋ค. ์ฆ, ์์ while๋ฌธ์ Board์ ๊ตฌํ์ ์์กดํ์ง ์๋ ๊ฒ์ด๋ค.
์ด ๋ง์ ๋ง์ผ ์ถํ์ Board์ ์งํฉ์ฒด๋ฅผ ์์ ํ๋๋ผ๋ Board ํด๋์ค๊ฐ ์ฌ๋ฐ๋ฅธ Iterator๋ง์ ๋ฐํํด ์ค๋ค๋ฉด ํด๋ผ์ด์ธํธ์ ์ฝ๋(์์ while ๋ฃจํ)๋ ๋ณ๊ฒฝํ์ง ์์๋ ๋๊ฒ ๋๋ค.
์ค๋ฌด์์ ์ฐพ์๋ณด๋ Iterator ํจํด
Java
- java.util.Enumeration ๊ณผ java.util.Iterator
- Java StAX (Streaming API for XML)์ Iterator ๊ธฐ๋ฐ API
- XmlEventReader, XmlEventWriter
java.util.Enumeration
- Iterator๊ฐ ๋ง๋ค์ด์ง๊ธฐ ์ java 1.0๋ถํฐ ์์๋ API
- ๊ณผ๊ฑฐ์ ํด๋์ค๋ก์, ํ์ฌ๋ ์์ฐ๊ณ Iterator๋ก ๊ธฐ๋ฅ์ด ๋์ฒด ๋์๋ค.
- java 9 ์์๋ Enumeration Iterator๋ก ๋ณํํด์ฃผ๋ ์ฝ๋๊ฐ ์ถ๊ฐ๋์๋ค.
asIterator()
Iterator | Enumeration |
์์๋ฅผ ๋ฐ๋ณตํ๋ ๋ฐ ์ฌ์ฉ๋๋ ์ผ๋ฐ ์ปค์์ด๋ฉฐ ๋ชจ๋ ์ปฌ๋ ์ ํด๋์ค์ ์ ์ฉํ ์ ์๋ค. | Vector์ ๊ฐ์ ๋ ๊ฑฐ์ ํด๋์ค์๋ง ์ ์ฉํ ์ ์์ผ๋ฏ๋ก ์ผ๋ฐ ์ปค์๊ฐ ์๋๋ค. ์ปฌ๋ ์ ํด๋์ค์ ๋ํ ์ฝ๊ธฐ ๊ถํ๋ง ์๋ค. |
๋ฐ๋ณต ๋ฉ์๋ : hasNext(), next() | ๋ฐ๋ณต ๋ฉ์๋ : hasMoreElements(), nextElement() |
๋ฐ๋ณต์๋ฅผ ์ฌ์ฉํ์ฌ ์ปฌ๋ ์ ์ ์์๋ฅผ ์ ๊ฑฐํ ์ ์๋ค. | ์ฝ๊ธฐ ๊ถํ๋ง ์๊ธฐ ๋๋ฌธ์ ์ด๊ฑฐ๋ฅผ ์ฌ์ฉํ์ฌ ์ปฌ๋ ์ ์ ์์๋ฅผ ์ ๊ฑฐํ ์ ์๋ค. |
public static void main(String[] args) {
Vector<Integer> rollno = new Vector<>();
rollno.add(1);
rollno.add(2);
rollno.add(3);
rollno.add(4);
rollno.add(5);
Enumeration<Integer> classNine = rollno.elements();
// hasMoreElements(), nextElement() ๋ก ์ํ
while (classNine.hasMoreElements()) {
System.out.println(classNine.nextElement());
}
}
java.util.Iterator
- hasNext() : ์ํํ ์์๊ฐ ์๋์ง ํ์ธ
- next() : ํ์ฌ ์ปค์์ ์์๋ฅผ ์ถ๋ ฅํ๊ณ ๋ค์์ผ๋ก ์ปค์๋ฅผ ์ด๋
- remove() : Iterator์์ next()๋ก ๋ฐ์๋ ํด๋น ์๋ฆฌ๋จผํธ๋ฅผ ์ญ์ .
- ๋ชจ๋ ์ดํฐ๋ ์ดํฐ์์ ๋ค ์ง์ํ๋ ๊ฒ์ ์๋๋ค. UnsupportedOperationException()์ ๋์ง๋ ๊ฒฝ์ฐ๊ฐ ๋ง๋ค.
- ๋ณดํต ์ด ๊ธฐ๋ฅ์ ๋์์ ๋ค๋ฐ์ ์ผ๋ก ๊ฐ์ ๋ช ๋ น์ ์ํํด๋ ์์ ํ ์ปฌ๋ ์ ์์ ์ ๊ณตํ๋ค.
- forEachRemaining() : ํจ์ํ ์ธํฐํ์ด์ค๋ฅผ ํตํด ์ํ ์ฝ๋๋ฅผ ์ฌํํ ํด์ค๋ค
public static void main(String[] args) {
Set<Integer> aggregate = new TreeSet<>(List.of(1,2,3,4,5));
// hasNext(), next(), remove()
Iterator<Integer> itr = aggregate.iterator();
while(itr.hasNext()) {
System.out.printf("%d ์ญ์ ", itr.next());
itr.remove();
}
System.out.println(aggregate); // []
}
public static void main(String[] args) {
Set<Integer> aggregate = new TreeSet<>(List.of(1,2,3,4,5));
// ์ดํฐ๋ ์ดํฐ์ while ๋ฌธ ์ฝ๋๋ฅผ for๋ฌธ์ผ๋ก ์ถ์ฝํ ์ ๋ ์๋ค.
for (Iterator<Integer> i = aggregate.iterator(); i.hasNext();) {
System.out.println(i.next());
}
// forEachRemaining()
aggregate.iterator().forEachRemaining(System.out::println);
}
Java StAX (Streaming API for XML)
- XML ํ์ผ ํฌ๋งท์ ์ฝ๊ฑฐ๋ ๋ง๋ค๋ ์ฌ์ฉํ๋ ์๋ฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ
- ์ฝ์ ๊ธฐ๋ฐ์ API, ์ดํฐ๋ ์ดํฐ ๊ธฐ๋ฐ์ API๋ฅผ ์ ๊ณตํ๋ค.
- ์ดํฐ๋ ์ดํฐ ๊ธฐ๋ฐ์ API : xml์ Element๋ง๋ค ์ด๋ฒคํธ๊ฐ ์ง๋๊ฐ๋ฉด์ ์บก์ณํ๋ฉฐ ๊ทธ ์์ญ์ ํํํ๋ XMLEvent๋ผ๋ ์ธ์คํด์ค๊ฐ ์๋ก ๋ง๋ค๊ณ ์ด๋ฅผ ์ด์ฉํ๋ ๋ฐฉ์์ด๋ค. (XmlEventReader, XmlEventWriter)
- ์ฝ์ ๊ธฐ๋ฐ์ API : ํ๋์ ์ธ์คํด์ค๊ฐ Element๋ฅผ ์ง๋๊ฐ๋ฉด์ ์ง์ ์์ ๋ด์ฉ๋ค์ ๋ณ๊ฒฝํ๋ ๋ฐฉ์์ด๋ค. ๊ทธ๋์ ๋ฉ๋ชจ๋ฆฌ๋ ์ดํฐ๋ ์ดํฐ ๊ธฐ๋ฐ๋ณด๋ค ํจ์จ์ ์ด์ง๋ง ์ฌ์ฌ์ฉ, ๋ณ๊ฒฝ ์ธก๋ฉด์์๋ ์ข์ง ์์ ์ดํฐ๋ ์ดํฐ ๊ธฐ๋ฐ์ API๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ๊ถ์ฅ๋๋ค.
- ๋น์ทํ SAX(Simple API for XML)๋ ์์ง๋ง, SAX๋ XML์ ์ฝ๊ธฐ๋ง ๊ฐ๋ฅํ๋ค.
์ดํฐ๋ ์ดํฐ ๊ธฐ๋ฐ์ API ์ฝ๋ ์์ ๋ ๋ค์๊ณผ ๊ฐ๋ค.
<?xml version="1.0" encoding="UTF-8"?>
<books>
<book title="์ค์ง์ด ๊ฒ์"/>
<book title="์จ๋ฐ๊ผญ์ง"/>
<book title="์ฐ๋ฆฌ์ง์ ์ ์๋"/>
</books>
public static void main(String[] args) throws FileNotFoundException, XMLStreamException {
// 1. XMLEventReader ๊ฐ์ฒด๋ฅผ ๋ง๋๋ ํฉํ ๋ฆฌ ๊ฐ์ฒด๋ฅผ ์ป๋๋ค.
XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
// 2. XMLEventReader ๊ฐ์ฒด๋ฅผ ๋ง๋ ๋ค.
XMLEventReader reader = xmlInputFactory.createXMLEventReader(new FileInputStream("book.xml"));
// 3. ์ดํฐ๋ ์ดํฐ ์ํํ๋ค.
while(reader.hasNext()) {
// <books> ์๋ฆฌ๋จผํธ๋ฅผ ์บก์ณํ์ฌ ๊ทธ ์์ญ์ ํํํ๋ XMLEvent ์ธ์คํด์ค๋ฅผ ์์ฑ
XMLEvent nextEvent = reader.nextEvent();
// ์๋ฆฌ๋จผํธ์ ์์ ์๋ฆฌ๋จผํธ๊ฐ ์์ ๊ฒฝ์ฐ
if(nextEvent.isStartElement()) {
StartElement startElement = nextEvent.asStartElement(); // <book>
QName name = startElement.getName();
if(name.getLocalPart().equals("book")) {
// ์๋ฆฌ๋จผํธ์ ์์ฑ์ ์ป๋๋ค. <book title=""/>
Attribute title = startElement.getAttributeByName(new QName("title"));
System.out.println(title.getValue());
}
}
}
}
Spring Framework
CompositeIterator
- ๊ธฐ์กด์ Interator์ add ๊ธฐ๋ฅ๋ง ํ๋ ์ถ๊ฐํ ๊ฒ
- add() : ์ฌ๋ฌ Iterator๋ค์ ์กฐํฉ(Composite)ํด์ ์ฌ์ฉํ ์ ์๋ค.
public class IteratorInSpring {
public static void main(String[] args) {
CompositeIterator iterator;
}
}
# ์ฐธ๊ณ ์๋ฃ
์ฝ๋ฉ์ผ๋ก ํ์ตํ๋ GoF์ ๋์์ธ ํจํด - ๋ฐฑ๊ธฐ์
https://refactoring.guru/design-patterns/iterator