๋ ์คํ ๋์๋, ๋ฉ๋ด๊ฐ ์ ํ์๋ ๋ฉ๋ดํ ์์
๋ ์คํ ๋์๋ ๋ฉ๋ดํ์ด 2๊ฐ๊ฐ ์์ผ๋ฉฐ, ์ฃผ๋ฌธ์ ๋ฐ๋ ์จ์ดํฐ๊ฐ ์์
๊ทธ๋ฐ๋ฐ, A๋ฉ๋ดํ์ ์๋ ๋ฉ๋ด๋ค์ ArrayList๋ก ๊ด๋ฆฌํ๊ณ , B๋ฉ๋ดํ์ ์๋ ๋ฉ๋ด๋ค์ Array๋ก ๊ด๋ฆฌํ๋ค๊ณ ๊ฐ์
์ฌ๊ธฐ์ ์๊ธธ ์ ์๋ ๋ฌธ์ ์
๋ฉ๋ดํ์ ์๋ ๋ฉ๋ด๋ค์ ๋ด์๋์ ์ปฌ๋ ์ ์ ์๋ฃ๊ตฌ์กฐ ํํ๊ฐ ๋ฌ๋ผ ์๊ธด ๋ฌธ์
์ด๋ฅผ ์ํด Iterator ์ธํฐํ์ด์ค๋ฅผ ๋ง๋ค๊ณ , Adapter ์ฒ๋ผ ์ฌ์ฉ ํ ์ ์์
interface Iterator<T> {
boolean hasNext();
T next();
}
class DinerMenuIterator implements Iterator<MenuItem> {
MenuItem[] items;
int position = 0;
public DinerMenuIterator(MenuItem[] items) {
this.items = items;
}
@override public MenuItem next() {
return items[position++];
}
@override public boolean hasNext() {
if (position > items.length || items[position] == null) {
return false;
}
return true;
}
}
class DinerMenu {
static final int MAX_ITEMS = 6;
int numberOfItems = 0;
MenuItem[] menuItems;
// add menu items / ...
// ์ด Iterator๋ฅผ ๊ฐ์ง๊ณ , ํด๋ผ์ด์ธํธ ( ์จ์ดํฐ ) DinerMenu์ ์๋ ๊ฐ๋ค์ ์กฐํํ ์ ์๋๋ก ํจ
public Iterator createIterator() {
return new DinerMenuIterator(menuItems);
}
}
class Waiter {
DinerMenu dinerMenu;
public Waiter(DinerMenu dinerMenu) {
this.dinerMenu = dinerMenu;
}
void printMenu() {
printMenu(dinerMenu.createIterator());
}
void printMenu(Iterator iterator) {
while(iterator.hasNext()) {
// print ๋ด์ฉ
}
}
}
Java.util.Iterator๋ฅผ ํ์ฉํ ์๋ ์์
interface Iterator<T> {
boolean hasNext();
T next();
void remove();
}
DinerMenu๋ ๊ตฌ์ฒด ํด๋์ค๋, ์ด๋ฅผ Menu ์ธํฐํ์ด์ค๋ก ์ถ์ํ
interface Menu {
public Iterator createIterator();
}
class Waiter {
Menu dinerMenu;
Menu pancakeMenu;
public Waiter(Menu dinerMenu, Menu pancakeMenu) {
this.dinerMenu = dinerMenu;
this.pancakeMenu = pancakeMenu;
}
void printMenu() {
printMenu(dinerMenu.createIterator());
printMenu(pancakeMenu.createIterator());
}
void printMenu(Iterator iterator) {
while(iterator.hasNext()) {
// print ๋ด์ฉ
}
}
}
์์ ๊ฐ์ด ๊ตฌํ ํ ๊ฒฝ์ฐ, Menu๊ฐ ๋์ด ๋ฌ์ ๋ Menu ๋ณ๋ก ์ฝ๋๋ฅผ ์ถ๊ฐ ํด์ฃผ์ด์ผ ํ๋ ๋ถํธํจ์ด ์์
๋ฐ๋ผ์ Menu๋ค์ ArrayList์ ๋ด์์ ํ์ฉ ๊ฐ๋ฅ
class Waiter {
ArrayList<Menu> menus;
public Waiter(ArrayList<Menu> menus) {
this.menus = menus;
}
void printMenu() {
Iterator menuIterator = menus.iterator();
while(menuIterator.hasNext()) {
printMenu(((Menu) menuIterator.next()).createIterator());
}
}
void printMenu(Iterator iterator) {
while(iterator.hasNext()) {
// print ๋ด์ฉ
}
}
}
class Waiter {
ArrayList<MenuComponent> menus;
public Waiter(ArrayList<Menu> menus) {
this.menus = menus;
}
void printMenu() {
Iterator menuIterator = menus.iterator();
while(menuIterator.hasNext()) {
printMenu(((Menu) menuIterator.next()).createIterator());
}
}
void printMenu(Iterator iterator) {
while(iterator.hasNext()) {
// print ๋ด์ฉ
}
}
}
์ด๋, DinerMenu ์์, DesertMenu๊ฐ ๋ค์ด๊ฐ์ผ ํ๋ ์ํฉ์ด ๋ฐ์ํ๋ค๊ณ ๊ฐ์
์ฆ, ์ ๋ ๋ฉ๋ดํ์์ ๋์ ํธ ๋ฉ๋ดํ ๋ด์ฉ์ด ํฌํจ ๋์ด์ผ ํ๋๋ฐ, ์ด๋ ์์ ๊ฐ์ ์๋ฃ๊ตฌ์กฐ ํํ์์๋ ๋ถ๊ฐ๋ฅํ ํํ ( MenuItem โ Menu )
๋ฐ๋ผ์, ์ปดํฌ์งํธ ํจํด์ ํ์ฉํ์ฌ Menu ( ๋ฉ๋ดํ )์ MenuItem ( ๊ฐ๋ณ ๋ฉ๋ด )๋ฅผ MenuComponent๋ก ํต์ผํจ
interface MenuComponent<MenuComponent> {
// ๋ฉ๋ดํ์ ํ์ํจ
void add(MenuComponent menuComponent)
...
// ๋ฉ๋ด์ ํ์ํจ
String getName();
boolean isVegetarian();
...
void print();
}
class MenuItem implements MenuComponent {
// MenuItem์์ ํ์ํ์ง ์์ MenuComponent ํจ์๋, ์๋ฌ๋ฅผ throw
@override void add(MenuComponent menuComponent) {
throw ...
}
@override String getName() {
return ...
}
@override void print() {
...
}
}
class Menu implements MenuComponent {
ArrayList<MenuComponent> menuComponents = new ArrayList();
// Menu์์ ํ์ํ์ง ์์ MenuComponent ํจ์๋, ์๋ฌ๋ฅผ throw
@override void add(MenuComponent menuComponent) {
menuComponents.add(menuComponent);
}
@override boolean isVegetarian() {
throw ...
}
@override void print() {
Iterator iterator = menuComponents.iterator();
while(iterator.hasNext()) {
MenuComponent menuComponent = (MenuComponent) iterator.next();
// ๋ฉ๋ดํ์ธ ๊ฒฝ์ฐ์ ์ฌ๊ท์ ์ผ๋ก MenuComponent๋ฅผ ๋ถ๋ฅด๋ฉฐ ํธ์ถ๋จ
menuComponent.print();
}
}
}
์ปดํฌ์งํธ ํจํด๊ณผ ์ดํฐ๋ ์ดํฐ ํจํด์ ํฉ์ณ, Component ( ๋ณตํฉ ๊ฐ์ฒด ์ ์ฒด ) ์์ iterator๋ฅผ ๋ฐ๋ก ๋ฝ์ ๋ผ ์ ์๋๋ก ๊ตฌํํ์ฌ, ๋ฐ๋ณต๋ฌธ์ ์ฌ์ฉ์ ํต์ผ์ฑ์ ์ค ์ ์์
์ฆ Iterator๋ฅผ Composite ์์๋, Leaf์์๋ ๋ฆฌํดํ๋๋ก ๊ตฌํ
interface MenuComponent {
// ๋ฉ๋ดํ์ ํ์ํจ
void add(MenuComponent menuComponent);
...
// ๋ฉ๋ด์ ํ์ํจ
String getName();
boolean isVegetarian();
...
void print();
...
// ์ถ๊ฐ๋ ๋ถ๋ถ
Iterator createIterator();
}
class MenuItem implements MenuComponent {
// MenuItem์์ ํ์ํ์ง ์์ MenuComponent ํจ์๋, ์๋ฌ๋ฅผ throw
@override void add(MenuComponent menuComponent) {
throw ...
}
@override String getName() {
return ...
}
@override void print() {
...
}
@override Iterator createIterator() {
// ์ปค์คํ
์ผ๋ก ๋ง๋ ๊ฒ
// default ํญ์ ๊ฐ์ ๋ฆฌํดํ๋๋ก ๊ตฌํ ํด๋ ๋จ
return NullIterator();
}
}
class NullIterator implements Iterator<MenuItem> {
@override MenuItem next() {
return null;
}
@override boolean hasNext() {
return false;
}
@override void remove() {
throw error ...
}
}
class Menu implements MenuComponent {
ArrayList<MenuComponent> menuComponents = new ArrayList();
// Menu์์ ํ์ํ์ง ์์ MenuComponent ํจ์๋, ์๋ฌ๋ฅผ throw
@override void add(MenuComponent menuComponent) {
menuComponents.add(menuComponent);
}
@override boolean isVegetarian() {
throw ...
}
@override void print() {
Iterator iterator = menuComponents.iterator();
while(iterator.hasNext()) {
MenuComponent menuComponent = (MenuComponent) iterator.next();
// ๋ฉ๋ดํ์ธ ๊ฒฝ์ฐ์ ์ฌ๊ท์ ์ผ๋ก MenuComponent๋ฅผ ๋ถ๋ฅด๋ฉฐ ํธ์ถ๋จ
menuComponent.print();
}
}
@override Iterator createIterator() {
// MenuComponent๋ Leaf๋, Composite๋ ๋ ์ ์์
// ๋ฐ๋ผ์ Leaf / Composite์ ๊ด๊ณ ์์ด ๋ฐ๋ณต์์
์ ํ ์ ์๋๋ก ๋ง๋ ํด๋์ค
return new CompositeIterator(menuComponents.iterator());
}
}
class CompositeIterator implements Iterator<MenuComponent> {
// Iterator ๊ฐ์ฒด๋ค์ ๋ด์๋์ stack
// ๋์ค์ ๋ค์ด์จ ๊ฒ์ ๋์ค์ ๊บผ๋ด๊ธฐ ์ํด ์ฌ์ฉํ์ผ๋,
Stack<Iterator> stack = new Stack();
public CompositeIterator(Iterator iterator) {
stack.push(iterator);
}
@override MenuComponent next() {
if (hasNext()) {
Iterator iterator = (Iterator) stack.peek();
MenuComponent component = (MenuComponent) iterator.next();
if (component instanceof Menu) { // ๋ฉ๋ดํ ( Composite ) ์ด๋ผ๋ฉด
// ๋ฉ๋ดํ์ ์๋ ๋ชจ๋ Menu component๋ฅผ stack์ ๋ด์๋์
stack.push(component.createIterator());
}
return component;
} else {
return null;
}
}
@override boolean hasNext() {
if (stack.isEmpty()) {
return false;
} else {
Iterator iterator = (Iterator) stack.peek();
if (!iterator.hasNext()) {
stack.pop();
return hasNext();
} else {
return true;
}
}
}
@override void remove() {
throw ... // ์ง์์ํจ
}
}
์ฑ์์ฃผ์์์ฉ ๋ฉ๋ด ์ฐพ๊ธฐ
class Waiter {
MenuComponent allMenues;
public Waiter(MenuComponent allMenues) {
this.allMenues = allMenues;
}
void printMenu() {
// ์ ์์์ฝ๋์ ๋ณ๊ฒฝ๋์ ์ ํ์ธ
allMenus.print();
}
void printMenuVegetarianMenu() {
Iterator iterator = allMenus.createIterator();
while (iterator.hasNext()) {
MenuComponent menuComponent = (MenuComponent) iterator.next();
try {
if (menuComponent.isVegetarian()) {
menuComponent.print();
}
} catch (Exception e) { } // isVegetarian์ ์ง์ํ์ง ์๋ ๋ฉ๋ดํ ๋๋ฌธ์ ์๋ฌ์ฒ๋ฆฌ
}
}
}