디자인 모드 chapter 09 - 교체 기 및 조합 모드

디자인 모드 chapter 09 - 교체 기 및 조합 모드
머리말
대상 을 쌓 아 집합 (collection) 으로 만 드 는 방법 은 많다.너 는 그들 을 배열, 스 택, 또는 흩 어 진 목록 에 넣 을 수 있다. 이것 은 너의 자유 이다.모든 것 은 자신의 장점 과 적당 한 사용 시기 가 있 지만 한 번 은 고객 이 이런 대상 을 옮 겨 다 니 고 싶 을 때 가 있 습 니 다. 그 가 이렇게 할 때 고객 에 게 당신 의 실현 을 보 여 주 려 고 합 니까?우 리 는 당연히 안 했 으 면 좋 겠 지!이 건 너무 프로 답지 못 하 다.괜 찮 습 니 다. 당신 의 일 에 대해 걱정 하지 마 세 요. 당신 은 이 장 에서 고객 이 당신 의 대상 을 옮 겨 다 니 며 저장 대상 을 엿 볼 수 없 는 방법 을 배 울 것 입 니 다.일부 대상 집합 (슈퍼 collection) 을 만 드 는 방법 도 배 워 서 보기 만 해도 무 서운 데이터 구 조 를 단숨에 뛰 어 넘 을 수 있 습 니 다.너 는 대상 의 직책 에 관 한 지식 도 배 울 것 이다.
본문
2.1 대상 마을 식당 과 대상 마을 전병 집 이 합병 되 었 다
이것 은 정말 좋 은 소식 이다. 이제 우 리 는 같은 곳 에서 두 가지 식품 을 사용 할 수 있 게 되 었 다.그런데 좀 귀 찮 은 것 같 아 요.부침 개 집 메뉴 는 배열 로 저장 되 고 식당 메뉴 는 Array List 로 저장 된다.적어도 두 식당 모두 아래 코드 에 따라 메뉴 항목 (단독 메뉴) 을 통일 한다.
메뉴 항목 구현:
public class MenuItem {
	String name;
	String description;
	boolean vegetarian;
	double price;
 
	/*
	 *         、  、     、  
	 *                   
	 * 
	 *    getter              
	 */
	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 double getPrice() {
		return price;
	}
  
	public boolean isVegetarian() {
		return vegetarian;
	}
}

부침 개 집 메뉴 구현
public class PancakeHouseMenu implements Menu {
	ArrayList menuItems;
 
	/*
	 *         
	 *     ArrayList       
	 *         ,            ArrayList 
	 * 
	 *         ,       :           ,       ,
	 *         ArrayList 
	 */
	public PancakeHouseMenu() {
		menuItems = new ArrayList();
    
		addItem("K&B's Pancake Breakfast", 
			"Pancakes with scrambled eggs, and toast", 
			true,
			2.99);
 
		addItem("Regular Pancake Breakfast", 
			"Pancakes with fried eggs, sausage", 
			false,
			2.99);
 
		addItem("Blueberry Pancakes",
			"Pancakes made with fresh blueberries",
			true,
			3.49);
 
		addItem("Waffles",
			"Waffles, with your choice of blueberries or strawberries",
			true,
			3.59);
	}

	public void addItem(String name, String description,
	                    boolean vegetarian, double price)
	{
		MenuItem menuItem = new MenuItem(name, description, vegetarian, price);
		menuItems.add(menuItem);
	}
 
	public ArrayList getMenuItems() {
		return menuItems;
	}

}

식당 메뉴 구현
public class DinerMenu implements Menu {
	static final int MAX_ITEMS = 6;
	int numberOfItems = 0;
	MenuItem[] menuItems;
  
	/*
	 * 1               ,           ,           ,      
	 * 2       ,      addItem()            
	 * 3 addItem()                    ,     。            
	 *             
	 */
	public DinerMenu() {
		menuItems = new MenuItem[MAX_ITEMS];
 
		addItem("Vegetarian BLT",
			"(Fakin') Bacon with lettuce & tomato on whole wheat", true, 2.99);
		addItem("BLT",
			"Bacon with lettuce & tomato on whole wheat", false, 2.99);
		addItem("Soup of the day",
			"Soup of the day, with a side of potato salad", false, 3.29);
		addItem("Hotdog",
			"A hot dog, with saurkraut, relish, onions, topped with cheese",
			false, 3.05);
		addItem("Steamed Veggies and Brown Rice",
			"Steamed vegetables over brown rice", true, 3.99);
		addItem("Pasta",
			"Spaghetti with Marinara Sauce, and a slice of sourdough bread",
			true, 3.89);
	}
  
	public void addItem(String name, String description, 
	                     boolean vegetarian, double price) 
	{
		MenuItem menuItem = new MenuItem(name, description, vegetarian, price);
		if (numberOfItems >= MAX_ITEMS) {
			System.err.println("Sorry, menu is full!  Can't add item to menu");
		} else {
			menuItems[numberOfItems] = menuItem;
			numberOfItems = numberOfItems + 1;
		}
	}
 
	public MenuItem[] getMenuItems() {
		return menuItems;
	}

}

이상 실현 의 단점:
1. 우 리 는 Pancake House Menu 와 Dinner Menu 의 구체 적 인 실현 코드 를 대상 으로 하 는 것 이지 인 터 페 이 스 를 대상 으로 하 는 것 이 아 닙 니 다.
2. 만약 에 우리 가 Dinner Menu 에서 다른 메뉴 로 전환 하기 로 결정 하면 이 메뉴 의 항목 은 Hash Table 로 저장 되 기 때문에 우 리 는 여급 중의 많은 코드 를 수정 해 야 합 니 다.
3. 여자 접 대 는 각 메뉴 가 내부 의 메뉴 항목 집합 을 어떻게 표현 하 는 지 알 아야 한다. 이것 은 포장 위반 이다.
4. 우 리 는 중복 되 는 코드 가 있 습 니 다. printMenu () 방법 은 두 가지 서로 다른 메뉴 를 옮 겨 다 니 는 두 가지 순환 이 필요 합 니 다.만약 우리 가 세 번 째 메뉴 를 더 한다 면, 우 리 는 세 가지 순환 이 필요 하 다.
2.2 회견 교체 기 모드
교체 기 모드 에 대해 알 아야 할 첫 번 째 일 은 교체 기 라 는 인터페이스 에 의존 하 는 것 이다.
하나의 교체 기 는 두 개의 인 터 페 이 스 를 포함 합 니 다. hasNext () 방법 은 이 집합 에 더 많은 요소 가 있 는 지 알려 줍 니 다. next () 방법 은 이 집합 중의 다음 대상 을 되 돌려 줍 니 다.
지금 우 리 는 식당 메뉴 를 위해 구체 적 인 교체 기 를 실현 해 야 한다.
public class DinerMenuIterator implements Iterator {
	MenuItem[] items;
	int position = 0;
 
	/*
	 *        
	 * 1 position           
	 * 2                     
	 * 3 next()             ,      
	 * 4 hasNext()                     。         ,   true
	 * 5             ,                      null
	 */
	public DinerMenuIterator(MenuItem[] items) {
		this.items = items;
	}
 
	public Object next() {
		MenuItem menuItem = items[position];
		position = position + 1;
		return menuItem;
	}
 
	public boolean hasNext() {
		if (position >= items.length || items[position] == null) {
			return false;
		} else {
			return true;
		}
	}
}

여급 코드
public class Waitress {
	Menu pancakeHouseMenu;
	Menu dinerMenu;
 
	public Waitress(Menu pancakeHouseMenu, Menu dinerMenu) {
		this.pancakeHouseMenu = pancakeHouseMenu;
		this.dinerMenu = dinerMenu;
	}
 
	public void printMenu() {
		Iterator pancakeIterator = pancakeHouseMenu.createIterator();
		Iterator dinerIterator = dinerMenu.createIterator();

		System.out.println("MENU
----
BREAKFAST"); printMenu(pancakeIterator); System.out.println("
LUNCH"); 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()); } } }

모든 것 을 정리 하기 전에 현재 의 디자인 을 전체적으로 살 펴 보 자.
1. 두 메뉴 가 같은 인 터 페 이 스 를 실현 합 니 다.
2. 부침 개 집 메뉴 와 식당 메뉴 는 모두 새로운 create Iterator () 방법 을 실 현 했 고 각자 의 메뉴 항목 에 교체 기 를 만 드 는 것 을 책임 집 니 다.
3. 교체 기 는 여급 이 구체 적 인 유형의 실현 에서 결합 을 풀 수 있 도록 한다.그녀 는 메뉴 가 배열, Array List 를 사용 하 는 지, 아니면 포스트 잇 을 사용 하 는 지 알 필요 가 없다.그녀 는 그녀 가 얻 을 수 있 는 교체 기 에 만 관심 이 있다.
2.3 교체 기 모드 정의
교체 기 모드: 집합 대상 의 각 요 소 를 방문 하고 내부 의 표 시 를 드 러 내지 않 는 방법 을 제공 합 니 다.
이것 은 매우 의미 가 있다. 이 모델 은 집합 대상 의 요 소 를 순서대로 방문 할 수 있 고 내부 가 어떻게 표시 되 는 지 모른다.
다른 팀 은 당신 의 디자인 에 중요 한 영향 을 미 쳤 습 니 다. 교체 기 모델 은 요소 사 이 를 돌아 다 니 는 책임 을 집적 대상 이 아니 라 교체 기 에 게 맡 깁 니 다.이 는 취 합 된 인터페이스 와 실현 을 더욱 간결 하 게 만 들 뿐만 아니 라 취 합 이 집중 해 야 할 일 에 도 집중 할 수 있다.
단일 책임: 한 가지 유형 은 변 화 를 일 으 키 는 원인 만 있어 야 한다.
클래스 의 모든 책임 은 변 하 는 잠재 적 인 구역 이 있다.하나의 책임 을 초과 하 는 것 은 변 화 된 지역 을 초과 하 는 것 을 의미한다.
이 원칙 은 우리 에 게 가능 한 한 모든 유형 이 단일 책임 을 유지 하도록 하 는 것 을 알려 준다.
어떻게 해결 할 까요?이것 은 듣 기 에는 매우 쉽 지만 사실은 하기 가 결코 간단 하지 않다. 디자인 의 책임 을 구분 하 는 것 이 가장 어 려 운 일 중의 하나 이다.우리 의 뇌 는 한 무리의 행동 을 보고 그들 을 한데 모 으 는 것 에 익숙 하 다.우리 의 뇌 는 한 무리의 행동 을 보고 그것 을 한데 모 으 는 것 에 익숙 하 다. 비록 그들 이 두 개 혹은 여러 개의 다른 책임 에 속 할 수 있 지만.
성공 하고 자 하 는 유일한 방법 은 당신 의 디자인 을 꾸준히 검사 하 는 것 입 니 다. 시스템 이 성장 함 에 따라 어떤 변화 가 나타 나 는 원인 이 하나 이상 인지 수시로 관찰 하 는 것 입 니 다.
2.4 교체 기와 집합
우리 가 사용 하 는 이 클래스 들 은 모두 자바 Collection Framework 의 일부분 에 속한다.여기 서 프레임 워 크 란 Array List, Vector, LinkedList, Stack 과 Priority Queue 를 포함 한 클래스 와 인 터 페 이 스 를 말한다.이 클래스 들 은 모두 자바 util. collection 인 터 페 이 스 를 실현 했다.이 인 터 페 이 스 는 많은 유용 한 방법 을 포함 하고 있어 서 한 무리의 대상 을 조종 할 수 있다.
자바 5 의 교체 기와 집합
자바 5 는 새로운 형세 의 for 문 구 를 포함 하여 for / in 이 되 었 다.이것 은 집합 이나 배열 을 옮 겨 다 닐 수 있 으 며, 명시 적 으로 교체 기 를 만 들 필요 가 없다.for / in 을 사용 하고 싶 습 니 다. 문법 은 이 렇 습 니 다.
for (Object obj: collection)
{
/ / 동작
}
2.5 초기 조합 모드
우리 가 이 모든 것 이 완벽 하 다 고 생각 할 때, 지금 그들 은 할 수 있 기 를 바란다.
디저트 를 곁 들 인 하위 메뉴.
만약 우리 가 디저트 메뉴 를 식당 메뉴 의 집합 요 소 를 프로 그래 밍 할 수 있다 면 얼마나 좋 을 까.하지만 지금의 실현 에 따라 근 거 는 할 수 없다.
그래서 우리 의 새로운 디자인 에서 정말 무엇이 필요 합 니까?
1 메뉴, 하위 메뉴, 메뉴 항목 을 수용 할 수 있 는 트 리 구조 가 필요 합 니 다.
2. 우 리 는 모든 메뉴 의 각 항목 사 이 를 돌아 다 닐 수 있 는 지 확인 해 야 한다. 그리고 적어도 지금 교체 기 를 사용 하 는 것 처럼 편리 해 야 한다.
3. 우리 도 메뉴 항목 사 이 를 좀 더 탄력 있 게 돌아 다 닐 수 있어 야 한다.예 를 들 어 디저트 메뉴 만 옮 겨 다 니 거나 식당 의 전체 메뉴 (디저트 메뉴 포함) 를 옮 겨 다 닐 수 있 습 니 다.
조합 모드: 대상 을 트 리 구조 로 조합 하여 '전체 / 부분' 차원 구 조 를 표현 할 수 있 도록 합 니 다.조합 은 고객 으로 하여 금 일치 하 는 방식 으로 개별 대상 과 대상 조합 을 처리 하 게 할 수 있다.
조합 모드 는 트 리 방식 으로 대상 의 구 조 를 만 들 수 있 고 트 리 에는 조합 과 개별 대상 이 포함 되 어 있 습 니 다.
조합 기 구 를 사용 하면 우 리 는 같은 조작 을 조합 과 개별 대상 에 응용 할 수 있다.대부분의 경우 대상 조합 과 개별 대상 간 의 차 이 를 무시 할 수 있다 는 얘 기다.
2.6 조합 디자인 메뉴 활용
우 리 는 어떻게 메뉴 에 조합 모드 를 적용 해 야 합 니까?처음에는 메뉴 와 메뉴 항목 의 공동 인터페이스 로 구성 요소 인 터 페 이 스 를 만들어 서 메뉴 와 메뉴 항목 을 통일 적 으로 처리 할 수 있 도록 해 야 합 니 다.메뉴 나 메뉴 항목 에 대해 같은 방법 을 사용 할 수 있다 는 얘 기다.
메뉴 구성 요 소 를 실현 하려 면 모든 구성 요소 가 MenuComponent 인 터 페 이 스 를 실현 해 야 합 니 다.그러나 잎 노드 와 조합 노드 의 역할 이 다 르 기 때문에 어떤 방법 은 특정한 노드 에 적합 하지 않 을 수 있다.이런 상황 에 직면 하여 때때로, 너 는 운행 시의 이상 을 직접 던 지 는 것 이 가장 좋다.
public abstract class MenuComponent {
   
	/*
	 *               ,           ,         。
	 *   ,             ,        ,            。
	 */
	public void add(MenuComponent menuComponent) {
		throw new UnsupportedOperationException();
	}
	public void remove(MenuComponent menuComponent) {
		throw new UnsupportedOperationException();
	}
	public MenuComponent getChild(int i) {
		throw new UnsupportedOperationException();
	}
  
	public String getName() {
		throw new UnsupportedOperationException();
	}
	public String getDescription() {
		throw new UnsupportedOperationException();
	}
	public double getPrice() {
		throw new UnsupportedOperationException();
	}
	public boolean isVegetarian() {
		throw new UnsupportedOperationException();
	}
  
	public void print() {
		throw new UnsupportedOperationException();
	}
}

메뉴 항목 구현
public class MenuItem extends MenuComponent {
	String name;
	String description;
	boolean vegetarian;
	double price;
    
	/*
	 * 1        MenuComponent  
	 * 2                ,   toString()  
	 */
	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 double getPrice() {
		return price;
	}
  
	public boolean isVegetarian() {
		return vegetarian;
	}
  
	public void print() {
		System.out.print("  " + getName());
		if (isVegetarian()) {
			System.out.print("(v)");
		}
		System.out.println(", " + getPrice());
		System.out.println("     -- " + getDescription());
	}
}

조합 메뉴 구현
public class Menu extends MenuComponent {
	ArrayList menuComponents = new ArrayList();
	String name;
	String description;
  
	/*
	 * 1         ,  MenuComponent
	 * 2              ,          MenuComponent  ,    ArrayList    
	 * 3                     。          MenuComponent,                  
	 * 4      ,            MenuComponent 
	 */
	public Menu(String name, String description) {
		this.name = name;
		this.description = description;
	}
 
	public void add(MenuComponent menuComponent) {
		menuComponents.add(menuComponent);
	}
 
	public void remove(MenuComponent menuComponent) {
		menuComponents.remove(menuComponent);
	}
 
	public MenuComponent getChild(int i) {
		return (MenuComponent)menuComponents.get(i);
	}
 
	public String getName() {
		return name;
	}
 
	public String getDescription() {
		return description;
	}
 
	public void print() {
		System.out.print("
" + getName()); System.out.println(", " + getDescription()); System.out.println("---------------------"); Iterator iterator = menuComponents.iterator(); while (iterator.hasNext()) { MenuComponent menuComponent = (MenuComponent)iterator.next(); menuComponent.print(); } } }

테스트 프로그램 작성
public class MenuTestDrive {
	public static void main(String args[]) {
		/*
		 * 1           
		 * 2             ,    allMenus
		 * 3        add()  ,             allMenu() 
		 * 4               
		 * 5                 
		 * 6                 ,         ,    ,             ,      
		 */
		MenuComponent pancakeHouseMenu = 
			new Menu("PANCAKE HOUSE MENU", "Breakfast");
		MenuComponent dinerMenu = 
			new Menu("DINER MENU", "Lunch");
		MenuComponent cafeMenu = 
			new Menu("CAFE MENU", "Dinner");
		MenuComponent dessertMenu = 
			new Menu("DESSERT MENU", "Dessert of course!");
		MenuComponent coffeeMenu = new Menu("COFFEE MENU", "Stuff to go with your afternoon coffee");
  
		MenuComponent allMenus = new Menu("ALL MENUS", "All menus combined");
  
		allMenus.add(pancakeHouseMenu);
		allMenus.add(dinerMenu);
		allMenus.add(cafeMenu);
  
		pancakeHouseMenu.add(new MenuItem(
			"K&B's Pancake Breakfast", 
			"Pancakes with scrambled eggs, and toast", 
			true,
			2.99));
		pancakeHouseMenu.add(new MenuItem(
			"Regular Pancake Breakfast", 
			"Pancakes with fried eggs, sausage", 
			false,
			2.99));
		pancakeHouseMenu.add(new MenuItem(
			"Blueberry Pancakes",
			"Pancakes made with fresh blueberries, and blueberry syrup",
			true,
			3.49));
		pancakeHouseMenu.add(new MenuItem(
			"Waffles",
			"Waffles, with your choice of blueberries or strawberries",
			true,
			3.59));

		dinerMenu.add(new MenuItem(
			"Vegetarian BLT",
			"(Fakin') Bacon with lettuce & tomato on whole wheat", 
			true, 
			2.99));
		dinerMenu.add(new MenuItem(
			"BLT",
			"Bacon with lettuce & tomato on whole wheat", 
			false, 
			2.99));
		dinerMenu.add(new MenuItem(
			"Soup of the day",
			"A bowl of the soup of the day, with a side of potato salad", 
			false, 
			3.29));
		dinerMenu.add(new MenuItem(
			"Hotdog",
			"A hot dog, with saurkraut, relish, onions, topped with cheese",
			false, 
			3.05));
		dinerMenu.add(new MenuItem(
			"Steamed Veggies and Brown Rice",
			"Steamed vegetables over brown rice", 
			true, 
			3.99));
 
		dinerMenu.add(new MenuItem(
			"Pasta",
			"Spaghetti with Marinara Sauce, and a slice of sourdough bread",
			true, 
			3.89));
   
		dinerMenu.add(dessertMenu);
  
		dessertMenu.add(new MenuItem(
			"Apple Pie",
			"Apple pie with a flakey crust, topped with vanilla icecream",
			true,
			1.59));
  
		dessertMenu.add(new MenuItem(
			"Cheesecake",
			"Creamy New York cheesecake, with a chocolate graham crust",
			true,
			1.99));
		dessertMenu.add(new MenuItem(
			"Sorbet",
			"A scoop of raspberry and a scoop of lime",
			true,
			1.89));

		cafeMenu.add(new MenuItem(
			"Veggie Burger and Air Fries",
			"Veggie burger on a whole wheat bun, lettuce, tomato, and fries",
			true, 
			3.99));
		cafeMenu.add(new MenuItem(
			"Soup of the day",
			"A cup of the soup of the day, with a side salad",
			false, 
			3.69));
		cafeMenu.add(new MenuItem(
			"Burrito",
			"A large burrito, with whole pinto beans, salsa, guacamole",
			true, 
			4.29));

		cafeMenu.add(coffeeMenu);

		coffeeMenu.add(new MenuItem(
			"Coffee Cake",
			"Crumbly cake topped with cinnamon and walnuts",
			true,
			1.59));
		coffeeMenu.add(new MenuItem(
			"Bagel",
			"Flavors include sesame, poppyseed, cinnamon raisin, pumpkin",
			false,
			0.69));
		coffeeMenu.add(new MenuItem(
			"Biscotti",
			"Three almond or hazelnut biscotti cookies",
			true,
			0.89));
 
		Waitress waitress = new Waitress(allMenus);
   
		waitress.printMenu();
	}
}

조합 모델 에 대한 작은 의문.
조합 모드 는 단일 책임 설계 원칙 으로 투명 성 (transparency) 을 얻는다.투명 성 이란 무엇 인가?구성 요소 와 인 터 페 이 스 를 관리 하 는 서브 노드 와 잎 노드 의 조작 을 동시에 포함 시 키 면 고객 은 조합 과 잎 노드 를 동일시 할 수 있다.즉, 하나의 요소 가 조합 인지 잎 노드 인지 고객 에 게 투명 하 다 는 것 이다.
그래서 위의 문제 로 돌아 가 는 것 은 전형 적 인 절충 사례 이다.비록 우 리 는 디자인 원칙 에 대해 알 고 있 지만, 우 리 는 항상 어떤 원칙 이 우리 디자인 에 미 치 는 영향 을 관찰 해 야 한다.때때로 우 리 는 고의로 원칙 에 어 긋 나 는 것 처럼 보 이 는 일 을 한다.
2.7 조합 교체 기
1. 우 리 는 Menu Component 에 create Iterator () 방법 을 추가 합 니 다. 이것 은 모든 메뉴 와 메뉴 항목 이 이 방법 을 실현 해 야 한 다 는 것 을 의미 합 니 다. 또한 하나의 조합 에 대해 Create Iterator () 방법 을 호출 하면 이 그룹의 모든 아이들 에 게 적 용 될 것 입 니 다.
2. 지금 우 리 는 메뉴 와 메뉴 항목 에서 이 방법 을 실현 해 야 한다.
이 Composite Iterator 는 무시 할 수 없 는 교체 기 이다.작업실 은 구성 요소 안의 메뉴 항목 을 옮 겨 다 니 며 모든 하위 메뉴 가 포함 되 어 있 는 지 확인 합 니 다.
주의: 여기 서 사용 하 는 재 귀 는 나 에 게 "재 귀 는 나의 친구 이 고 재 귀 는 나의 친구 이다..." 라 고 묵념 했다.
public class CompositeIterator implements Iterator {
	Stack stack = new Stack();
   
	public CompositeIterator(Iterator iterator) {
		stack.push(iterator);
	}
   
	/*
	 * (non-Javadoc)
	 * @see java.util.Iterator#next()
	 * 1                ,     hasNext()          
	 * 2          ,               ,           
	 * 3           ,                   ,           。        ,        。
	 */
	public Object next() {
		if (hasNext()) {
			Iterator iterator = (Iterator) stack.peek();
			MenuComponent component = (MenuComponent) iterator.next();
			if (component instanceof Menu) {
				stack.push(component.createIterator());
			} 
			return component;
		} else {
			return null;
		}
	}
  
	/*
	 * (non-Javadoc)
	 * @see java.util.Iterator#hasNext()
	 * 1              ,           ;      ,           
	 * 2   ,               ,           ,      ,        ,       hasNext()
	 * 3   ,         ,    true
	 */
	public boolean hasNext() {
		if (stack.empty()) {
			return false;
		} else {
			Iterator iterator = (Iterator) stack.peek();
			if (!iterator.hasNext()) {
				stack.pop();
				return hasNext();
			} else {
				return true;
			}
		}
	}
   
	public void remove() {
		throw new UnsupportedOperationException();
	}
}

3 장 소결
아주 긴 장, 코드 필름 도 적지 않 았 는데, 다행히 마침내 끝 이 났 다.학습 과정 에서 우 리 는 이런 상대 적 으로 긴 학습 주 기 를 자주 만 날 수 있다. 이 럴 때 여러 단계 로 나 누 어 완성 할 수 있 고 자신의 진 도 를 실시 간 으로 기록 할 수 있다. 간단 한 미 완성 / 이미 완성 이 아니 라 일정한 격려 역할 을 할 수 있다.
이 디자인 모델 로 돌아 가면 교체 기 는 낯 설 지 않 을 것 입 니 다. 여기 서 교체 기 인 터 페 이 스 를 사용자 정의 한 것 은 바로 교체 기의 작업 원 리 를 알 게 해 주 는 것 입 니 다.조합 모드 는 재 귀 알고리즘 과 결합 하여 트 리 구 조 를 처리 할 때 절대 이기 입 니 다.이전에 작은 도 구 를 쓸 때 도 비슷 한 문제 에 부 딪 힌 적 이 있다. 그 때 는 이런 이기 가 있 는 지 몰 랐 고 자신의 생각 으로 기능 을 실현 했다. 최적화 가능성 이 있 는 지 돌 이 켜 보 았 다.수 요 는 간단 합 니 다. Excel 의 기록 을 트 리 구조 에 따라 xml 파일 로 출력 합 니 다. 관심 이 있 는 학생 들 은 제 이전 블 로 그 를 볼 수 있 습 니 다 (http://blog.csdn.net/adoaiwen1314/article/details/17075491) 조합 교체 기 모드 로 디자인 된 코드 를 제시 한 것 을 환영 합 니 다.

좋은 웹페이지 즐겨찾기