Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- nodejs
- Redux
- web
- 주짓수
- git
- Node
- REACT
- 자바스크립트
- 드릴
- 노드
- 하프가드
- 영화
- 주짓떼라
- Express
- 프로그래밍
- 파이썬
- 주짓떼로
- 웹개발
- 엄티로드
- 영화리뷰
- 클로즈가드
- graphQL
- 리액트
- JavaScript
- development
- 개발자
- 영화감상
- 솔로드릴
- 개발
- 디자인패턴
Archives
- Today
- Total
As i wish
[Design pattern] Iterator pattern (이터레이터 패턴) 본문
오늘은 이터레이터 패턴에 대하여 포스팅해보겠습니다.
일단 정의부터 보시죠.
이터레이터 패턴
컬렉션을 표현하는 방법을 노출시키지 않으면서도 집합체 내에 있는 모든 객체들에 하나씩 접근하는 방법을 제공합니다.
반복자를 이용하여 내부 구조를 드러내지 않으면서도 클라이언트로부터 컬렉션 안에 들어 있는 모든 원소들을 접근할 수 있게 만듭니다.
예를 들어 설명해 보겠습니다.
어떤 컬렉션에서는 List로 아이템 원소들을 관리하고, 다른 컬렉션에서는 Dictionary로 아이템을 관리한다고 했을 때에 클라이언트 입장에서는 두 개의 원소들을 나열하려고 할 때 각기 다른 방법으로 나열해야 합니다. 하지만 이터레이터 패턴을 사용하면, 어떤 식으로 내부 구조가 짜여있던지 상관없이 클라이언트는 반복자를 이용하려 아이템을 나열할 수 있습니다.
# -*- coding: utf-8 -*-
# Iterator Pattern
import abc
class Menu:
__metaclass__ = abc.ABCMeta
@abc.abstractmethod
def createIterator(self):
pass
class Iterator:
__metaclass__ = abc.ABCMeta
@abc.abstractmethod
def hasNext(self):
pass
@abc.abstractmethod
def next(self):
pass
class Waitress:
def __init__(self, pancakeHouseMenu, dinerMenu):
self.pancakeHouseMenu = pancakeHouseMenu
self.dinerMenu = dinerMenu
def printMenu(self):
pancakeIterator = self.pancakeHouseMenu.createIterator()
dinerIterator = self.dinerMenu.createIterator()
print("MENU PANCAKE")
self._printMenu(pancakeIterator)
print("MENU DINER")
self._printMenu(dinerIterator)
def _printMenu(self, iterator):
while iterator.hasNext():
menuItem = iterator.next()
print ("%s , " %menuItem.getName())
print ("%s , " %menuItem.getPrice())
print ("%s , " %menuItem.getDescription())
class MenuItem:
def __init__(self, name, description, vegetarian, price):
self.name = name
self.description = description
self.vegetarian = vegetarian
self.price = price
def getName(self):
return self.name;
def getDescription(self):
return self.description
def isVegetarian(self):
return self.vegetarian
def getPrice(self):
return self.price
class PancakeHouseMenu(Menu):
def __init__(self):
self.menuItems = []
self.addMenu('K&B PancakeSet', 'Scramble egg and toast', True, 2.99)
self.addMenu('Regular PancakeSet', 'Egg fry, suasage', False, 2.99)
self.addMenu('Blueberry PancakeSet', 'Add blueberry', True, 3.49)
def addMenu(self, name, description, vegetarian, price):
self.menuItems.append(MenuItem(name, description, vegetarian, price))
# def getMenuItems(self):
# return self.menuItems
def createIterator(self):
return PancakeHouseIterator(self.menuItems)
class DinerMenu(Menu):
def __init__(self):
self.menuItems = {}
self.addMenu('Vegetarian BLT', 'Bread and tomato', True, 2.99)
self.addMenu('BLT', 'Bread and bacon', False, 2.99)
self.addMenu('Today soup', 'Potato soup', False, 3.49)
def addMenu(self, name, description, vegetarian, price):
self.menuItems[name] = MenuItem(name, description, vegetarian, price)
# def getMenuItems(self):
# return self.menuItems
def createIterator(self):
return DinerMenuIterator(self.menuItems)
class PancakeHouseIterator(Iterator):
def __init__(self, item):
# List
self.item = item
self.position = 0
def hasNext(self):
return len(self.item) > 0
def next(self):
return self.item.pop()
class DinerMenuIterator(Iterator):
def __init__(self, item):
# Dictionary
self.item = item
self.itemValues = self.item.values()
def hasNext(self):
return len(self.itemValues) > 0
def next(self):
return self.itemValues.pop()
# Client
pancakeHouseMenu = PancakeHouseMenu()
dinerMenu = DinerMenu()
waitress = Waitress(pancakeHouseMenu, dinerMenu)
waitress.printMenu()
위처럼 PancakePancakeHouseIterator, DinerMenuIterator를 만들어서 Waitress 가 메뉴를 출력할 때 각각의 메뉴들 (PancakeHouseMenu, DinerMenu)의 메뉴 아이템들이 어떤 형식(PancakeHouseMenu: List, DinerMenu: Dictionary)으로 구성되어있는지 모르고 그냥 반복자를 이용하여 아이템들을 나열할 수 있습니다.
<결과>
파이썬에서는 내장 함수로 iterator를 제공해주고 있는데요.
한번 써보겠습니다.
# -*- coding: utf-8 -*-
# Iterator Pattern
import abc
class Menu:
__metaclass__ = abc.ABCMeta
@abc.abstractmethod
def createIterator(self):
pass
class Iterator:
__metaclass__ = abc.ABCMeta
@abc.abstractmethod
def hasNext(self):
pass
@abc.abstractmethod
def next(self):
pass
class Waitress:
def __init__(self, pancakeHouseMenu, dinerMenu):
self.pancakeHouseMenu = pancakeHouseMenu
self.dinerMenu = dinerMenu
def printMenu(self):
pancakeIterator = self.pancakeHouseMenu.createIterator()
dinerIterator = self.dinerMenu.createIterator()
print("MENU PANCAKE")
self._printMenu(pancakeIterator)
print("MENU DINER")
self._printMenu(dinerIterator)
def _printMenu(self, iterator):
# while iterator.hasNext():
# menuItem = iterator.next()
# print ("%s , " %menuItem.getName())
# print ("%s , " %menuItem.getPrice())
# print ("%s , " %menuItem.getDescription())
while True:
try:
menuItem = next(iterator) # <--- use python inner function
print ("%s , " %menuItem.getName())
print ("%s , " %menuItem.getPrice())
print ("%s , " %menuItem.getDescription())
except StopIteration:
break
class MenuItem:
def __init__(self, name, description, vegetarian, price):
self.name = name
self.description = description
self.vegetarian = vegetarian
self.price = price
def getName(self):
return self.name;
def getDescription(self):
return self.description
def isVegetarian(self):
return self.vegetarian
def getPrice(self):
return self.price
class PancakeHouseMenu(Menu):
def __init__(self):
self.menuItems = []
self.addMenu('K&B PancakeSet', 'Scramble egg and toast', True, 2.99)
self.addMenu('Regular PancakeSet', 'Egg fry, suasage', False, 2.99)
self.addMenu('Blueberry PancakeSet', 'Add blueberry', True, 3.49)
def addMenu(self, name, description, vegetarian, price):
self.menuItems.append(MenuItem(name, description, vegetarian, price))
# def getMenuItems(self):
# return self.menuItems
def createIterator(self):
# return PancakeHouseIterator(self.menuItems)
return iter(self.menuItems) # <--- python inner function
class DinerMenu(Menu):
def __init__(self):
self.menuItems = {}
self.addMenu('Vegetarian BLT', 'Bread and tomato', True, 2.99)
self.addMenu('BLT', 'Bread and bacon', False, 2.99)
self.addMenu('Today soup', 'Potato soup', False, 3.49)
def addMenu(self, name, description, vegetarian, price):
self.menuItems[name] = MenuItem(name, description, vegetarian, price)
# def getMenuItems(self):
# return self.menuItems
def createIterator(self):
# return DinerMenuIterator(self.menuItems)
return iter(self.menuItems.values()) # <--- python inner function
class PancakeHouseIterator(Iterator):
def __init__(self, item):
# List
self.item = item
self.position = 0
def hasNext(self):
return len(self.item) > 0
def next(self):
return self.item.pop()
class DinerMenuIterator(Iterator):
def __init__(self, item):
# Dictionary
self.item = item
self.itemValues = self.item.values()
def hasNext(self):
return len(self.itemValues) > 0
def next(self):
return self.itemValues.pop()
# Client
pancakeHouseMenu = PancakeHouseMenu()
dinerMenu = DinerMenu()
waitress = Waitress(pancakeHouseMenu, dinerMenu)
waitress.printMenu()
해보시면 아시겠지만 당연하게도 결과는 같습니다.!!!
정말 편하네요 위에 코드에서 '<---' 된 부분은 파이썬 내장 함수를 사용하면서 변경된 부분입니다.
'Design Pattern' 카테고리의 다른 글
[Design pattern] State pattern (스테이트 패턴, 상태 패턴) (0) | 2019.05.31 |
---|---|
[Design pattern] Composite pattern (컴포지트 패턴) (0) | 2019.05.23 |
[Design pattern] Template method pattern (템플릿 메서드 패턴) (0) | 2019.05.05 |
[Design pattern] 데코레이터 vs 어댑터 vs 퍼사드 패턴 (0) | 2019.04.22 |
[Design pattern] Facade pattern (퍼사드패턴) (0) | 2019.04.22 |
Comments