1) 의미 및 구현방법
for 문이나 기타 반복문을 클래스단위로 쪼갤수 있습니다.
장점은 for문 도배를 피할수 있다는거고(복잡도를 나눈다)
단점은 클래스가 많아지는점?
요건 다른것과 틀리게 패턴으로 한번 봐둬야 일할때
헷갈림 방지가 가능합니다.
for 문의 i 의 기능을 추상화해서 일반화 하는걸 Iterator pattern
이라고도 표현하기도 합니다.
2) 참고자료
2. 소스
1) 이터레이터 interface와 그 구현체를 작성한다.
반복역할을 직접 담당하는 이터레이터는 hasNext(체크)
next(객체 선택) 메서드를 구현하도록 강요하여
배열로 집어넣은 객체를 처음부터 끝까지 뒤져볼 수 있도록
합니다.
package iterator; public interface Iterator { boolean hasNext(); Object next(); }
package iterator; import serviceMenu.MenuItem; public class DinerMenuIterator implements Iterator{ MenuItem[] items; int position=0; public DinerMenuIterator(MenuItem[] items){ this.items=items; } @Override public boolean hasNext() { if(position >= items.length || items[position] == null){ return false; }else { return true; } } @Override public Object next() { MenuItem menuItem = items[position]; position = position +1; return menuItem; } }
package iterator; import serviceMenu.MenuItem; public class PancakeHouseMenuIterator implements Iterator{ MenuItem[] items; int position=0; public PancakeHouseMenuIterator(MenuItem[] items){ this.items=items; } @Override public boolean hasNext() { if(position >= items.length || items[position] == null){ return false; }else { return true; } } @Override public Object next() { MenuItem menuItem = items[position]; position = position +1; return menuItem; } }
2) aggregate 는 집합체 구성원을 추가하거나 정보를 관리하는
역할을 담당합니다. interface를 통해서 Iterator를 반환하는
메서드를 강제하도록 작성하고
각 구현체에서 여기에 집합객체를 넣도록 구현합니다.
여기까지 진행된다면 각 구현체가 Iterator 객체의
어떤 구현체를 사용할 건지 정할 수 있습니다.
package menu; import iterator.Iterator; import serviceMenu.MenuItem; public interface MenuAggr { public Iterator createIterator(); }
package menu; import serviceMenu.MenuItem; import iterator.DinerMenuIterator; import iterator.Iterator; public class DinerMenu implements MenuAggr{ static final int MAX_ITEMS =6; int numberOfItems = 0; MenuItem[] menuItems; public DinerMenu(){ menuItems = new MenuItem[MAX_ITEMS]; addItem("diner1","dier1des",true,2.99); addItem("diner2","dier2des",false,3.99); addItem("diner3","dier3des",true,2.49); addItem("diner4","dier4des",true,3.97); } public void addItem(String name, String description, boolean vegetarian, double price){ MenuItem menuItem = new MenuItem(name, description, vegetarian, price); if(numberOfItems >= MAX_ITEMS){ System.out.println("더이상 메뉴를 추가할 수 없음"); }else{ menuItems[numberOfItems] = menuItem; numberOfItems = numberOfItems +1; } } public MenuItem[] getMenuItems(){ return menuItems; } public Iterator createIterator(){ return new DinerMenuIterator(menuItems); } }
package menu; import iterator.DinerMenuIterator; import iterator.Iterator; import java.util.ArrayList; import serviceMenu.MenuItem; public class PancakeHouseMenu implements MenuAggr{ static final int MAX_ITEMS =6; int numberOfItems = 0; MenuItem[] menuItems; public PancakeHouseMenu(){ menuItems = new MenuItem[MAX_ITEMS]; addItem("cake1","cake1des",true,2.99); addItem("cake2","cake2des",false,3.99); addItem("cake3","cake3des",true,2.49); addItem("cake4","cake4des",true,3.97); } public void addItem(String name, String description, boolean vegetarian, double price){ MenuItem menuItem = new MenuItem(name, description, vegetarian, price); if(numberOfItems >= MAX_ITEMS){ System.out.println("더이상 메뉴를 추가할 수 없음"); }else{ menuItems[numberOfItems] = menuItem; numberOfItems = numberOfItems +1; } } public MenuItem[] getMenuItems(){ return menuItems; } public Iterator createIterator(){ return new DinerMenuIterator(menuItems); } }
3) 객체 하나에 대한 정보를 관리하는 대상객체를 작성합니다.
여기에는 get 함수만 활용하도록 강제합니다.
set은 따로 관리하지 않고 생성자에서 생성시 들어가도록
관리합니다.
4) 이들을 묶어서 실제 객체만큼 출력이나 행동을 담당할
웨이트레스 클래스를 작성합니다.
5) 이를 테스트 해보기 위한 소스
여기에는 get 함수만 활용하도록 강제합니다.
set은 따로 관리하지 않고 생성자에서 생성시 들어가도록
관리합니다.
package serviceMenu; public class MenuItem { String name; String description; boolean vegetarian; double price; public MenuItem(String name, String description, boolean vegetarian, double price){ this.name = name; this.description=description; this.vegetarian=vegetarian; this.price=price; } public String getName() { return name; } public String getDescription() { return description; } public boolean isVegetarian() { return vegetarian; } public double getPrice() { return price; } }
4) 이들을 묶어서 실제 객체만큼 출력이나 행동을 담당할
웨이트레스 클래스를 작성합니다.
package testWoker; import serviceMenu.MenuItem; import menu.DinerMenu; import menu.PancakeHouseMenu; import iterator.Iterator; public class Waitress { PancakeHouseMenu pancakeHouseMenu; DinerMenu dinerMenu; public Waitress(PancakeHouseMenu pancakeHouseMenu, DinerMenu dinerMenu){ this.pancakeHouseMenu=pancakeHouseMenu; this.dinerMenu=dinerMenu; } public void printMenu(){ Iterator pancakeIterator = pancakeHouseMenu.createIterator(); Iterator dinerIterator = dinerMenu.createIterator(); System.out.println("아침"); printMenu(pancakeIterator); System.out.println("점심"); printMenu(dinerIterator); } private void printMenu(Iterator iterator){ while(iterator.hasNext()){ MenuItem menuItem = (MenuItem) iterator.next(); System.out.print(menuItem.getName()+","); System.out.print(menuItem.getPrice()+"--"); System.out.println(menuItem.getDescription()); } } }
5) 이를 테스트 해보기 위한 소스
package testWoker; import menu.DinerMenu; import menu.PancakeHouseMenu; public class SampleMenu { public static void main(String[] args) { PancakeHouseMenu cake = new PancakeHouseMenu(); DinerMenu diner = new DinerMenu(); Waitress wait = new Waitress(cake, diner); wait.printMenu(); } }
결과 : 아침
cake1,2.99--cake1des
cake2,3.99--cake2des
cake3,2.49--cake3des
cake4,3.97--cake4des
점심
diner1,2.99--dier1des
diner2,3.99--dier2des
diner3,2.49--dier3des
diner4,3.97--dier4des
cake1,2.99--cake1des
cake2,3.99--cake2des
cake3,2.49--cake3des
cake4,3.97--cake4des
점심
diner1,2.99--dier1des
diner2,3.99--dier2des
diner3,2.49--dier3des
diner4,3.97--dier4des
3. 다이어그램
3) 다이어그램
역시 하단 링크를 참고바랍니다.
하단 링크에서도 자세하게 설명하고 있습니다.
http://secretroute.tistory.com/entry/Head-First-Design-Patterns-%EC%A0%9C9%EC%9E%A5-Iterator-%EC%99%80-Composite-%ED%8C%A8%ED%84%B4
4. 연관 있는 패턴들
1) Visitor 패턴
Iterator가 집합체 숫자를 세는 패턴이라면
Visitor는 숫자를 셀때 뭔가 작업을 추가하여
여러 모여있는 instance에 공통 작업을 부여 할 수 있습니다.
2) Composite 패턴
Iterator와 비슷하지만 Composite는 재귀적인 구조로
작성되므로 비슷한 기능을 하는 다른 패턴입니다.
3) Factory Method 패턴
iterator 매서드가 Iterator 인스턴스를 작성시 해당 패턴이
사용될 수 있습니다.
댓글 없음:
댓글 쓰기