반복기 패턴
Iterator pattern객체 지향 프로그래밍에서 반복자 패턴은 반복자가 컨테이너를 통과하고 컨테이너의 요소에 액세스하기 위해 사용되는 설계 패턴입니다.반복기 패턴은 컨테이너에서 알고리즘을 분리합니다. 경우에 따라 알고리즘은 반드시 컨테이너에 고유하므로 분리할 수 없습니다.
예를 들어 가상 알고리즘 Search For Element는 컨테이너 고유의 알고리즘으로 구현하지 않고 일반적으로 지정된 유형의 반복기를 사용하여 구현할 수 있습니다.따라서 SearchForElement는 필요한 유형의 반복기를 지원하는 모든 컨테이너에서 사용할 수 있습니다.
개요
반복기 설계 패턴은 반복적인 설계 문제를 해결하고 유연하고 재사용 가능한 객체 지향 소프트웨어, 즉 구현, 변경, 테스트 및 재사용이 용이한 객체를 설계하는 방법을 설명하는 잘 알려진 23가지 GoF 설계 패턴 중 하나입니다.
반복기 설계 패턴으로 해결할 수 있는 문제는 무엇입니까?
- 집약 객체의 요소는 표현(데이터 구조)을 노출하지 않고 접근 및 통과해야 합니다.
- 인터페이스를 변경하지 않고 집약 객체에 대해 새로운 트래버설 작업을 정의해야 합니다.
집약 인터페이스에서 액세스 및 트래버설 조작을 정의하는 것은 특정 액세스 및 트래버설 조작에 집약을 커밋하고 나중에 집약 인터페이스를 변경하지 않으면 새로운 조작을 추가할 수 없기 때문에 유연성이 떨어집니다.
Iterator 설계 패턴은 어떤 솔루션을 설명합니까?
- 집약 객체에 대한 액세스 및 통과를 캡슐화하는 개별(반복기) 객체를 정의합니다.
- 클라이언트는 표현(데이터 구조)을 인식하지 않고 반복기를 사용하여 Aggregate에 액세스하고 Aggregate를 통과합니다.
서로 다른 반복기를 사용하여 서로 다른 방법으로 집계에 액세스하고 집계를 통과할 수 있습니다.
새로운 액세스 조작과 트래버설 조작은, 새로운 반복기를 정의해 개별적으로 정의할 수 있습니다.
아래 UML 클래스 및 시퀀스 다이어그램을 참조하십시오.
정의.
반복기 패턴의 본질은 "기본 [3]표현을 노출하지 않고 집합 객체의 요소에 순차적으로 액세스할 수 있는 방법을 제공하는 것"입니다.
구조.
UML 클래스 및 시퀀스 다이어그램

위의 UML 클래스 다이어그램에서는Client
class는 (1)을 참조한다.Aggregate
인터페이스 생성Iterator
오브젝트(createIterator()
( ) 및 (2)는Iterator
를 통과하기 위한 인터페이스Aggregate
오브젝트(next(),hasNext()
).Iterator1
class는 다음 명령을 실행합니다.Iterator
액세스에 의한 인터페이스Aggregate1
학급.
UML 시퀀스 다이어그램은 런타임 상호 작용을 보여 줍니다.그Client
오브젝트 콜createIterator()
을 타고Aggregate1
object를 생성한다.Iterator1
object를 반환한다.Client
.그Client
다음에 사용하다Iterator1
의 요소를 횡단하다Aggregate1
물건.
UML 클래스 다이어그램
언어 고유의 구현
일부 언어는 구문을 표준화합니다.C++와 Python이 주목할 만한 예입니다.
C#
.NET Framework에는 단순한 반복을 지원하는 특별한 인터페이스가 있습니다.System.Collections.IEnumerator
비독점적인 콜렉션과System.Collections.Generic.IEnumerator<T>
일반 컬렉션에 대해 설명하겠습니다.
C#문foreach
를 구현한 컬렉션을 쉽게 반복할 수 있도록 설계되어 있습니다.System.Collections.IEnumerator
및/또는System.Collections.Generic.IEnumerator<T>
인터페이스입니다.C# v2부터foreach
또, 실장하는 타입을 통해서 반복할 수 있습니다.System.Collections.Generic.IEnumerable<T>
그리고.System.Collections.Generic.IEnumerator<T>
[5]
사용 예foreach
스테이트먼트:
변화하다 소수점 = 신규 목록.< >인트>{ 2, 3, 5, 7, 11, 13, 17, 19 }; 긴 m = 1; 앞지르다 (변화하다 p 에 소수점) m *= p;
C++
C++ 는, 그 언어의 포인터의 시멘틱스를 사용해 반복기를 실장합니다.C++에서는 클래스가 모든 포인터 조작을 오버로드 할 수 있기 때문에 디레퍼런스, 인크리먼트 및 디크리먼트로 어느 정도 포인터처럼 동작하는 반복기를 실장할 수 있습니다.이것은, 다음과 같은 C++ 알고리즘의 이점이 있습니다.std::sort
는 플레인오래된 메모리버퍼에 즉시 적용할 수 있으며 학습할 새로운 구문은 없습니다.그러나, 이것은 반복자가 자신이 종말에 도달했다는 것을 알게 하는 것이 아니라 평등을 테스트하기 위해 "종말" 반복자를 필요로 합니다.C++ 언어에서는 반복자가 반복자 개념을 모델링한다고 합니다.
자바
Java는Iterator
인터페이스입니다.
를 사용하여 [start, end] 사이의 정수를 반환하는 간단한 예를 나타냅니다.Iterator
수입품 java.displaces를 클릭합니다.반복기; 수입품 java.displaces를 클릭합니다.No Such Element(수치 요소 없음)예외.; 일반의 학급 RangeIterator 예시 { 일반의 정적인 반복기< >정수> 범위(인트 개시하다, 인트 끝.) { 돌아가다 신규 반복기<< 고객명 >>님() { 사적인 인트 색인 = 개시하다; @오버라이드 일반의 부울 다음() { 돌아가다 색인 < > 끝.; } @오버라이드 일반의 정수 다음 분.() { 한다면 (!다음()) { 던지다 신규 No Such Element(수치 요소 없음)예외.(); } 돌아가다 색인++; } }; } 일반의 정적인 무효 주된(스트링[] args) { 변화하다 리터레이터 = 범위(0, 10); 하는 동안에 (리터레이터.다음()) { 시스템..나가..인쇄(리터레이터.다음 분.()); } // 또는 람다 사용 리터레이터.각각 나머지(시스템..나가.::인쇄); } }
Java 5의 시점에서는 다음 명령어를 실장하고 있는 오브젝트Iterable
interface: 인터페이스:Iterator
Java의 foreach 루프 구문을 사용하여 통과할 수 있습니다.그Collection
Java 컬렉션 프레임워크에서 인터페이스가 확장됩니다.Iterable
.
클래스의 예Family
실장Iterable
인터페이스:
수입품 java.displaces를 클릭합니다.반복기; 수입품 java.displaces를 클릭합니다.세트; 학급 가족< >E> 용구 반복할 수 있다< >E> { 사적인 최종 세트< >E> 요소들; 일반의 가족(세트< >E> 요소들) { 이것..요소들 = 세트.카피오(요소들); } @오버라이드 일반의 반복기< >E> 리터레이터() { 돌아가다 요소들.리터레이터(); } }
학급.IterableExample
수업의 이용을 증명하다Family
:
일반의 학급 Itable 예 { 일반의 정적인 무효 주된(스트링[] args) { 변화하다 족제비 = 세트.의( '아더', '몰리', "청구서, '찰리', 퍼시, "프레드", "조지", '론', "초기" ); 변화하다 가족 = 신규 가족<< 고객명 >>님(족제비); 위해서 (변화하다 이름. : 가족) { 시스템..나가..인쇄(이름. + '위즐리); } } }
출력:
론 위즐리 몰리 위즐리 퍼시 위즐리 프레드 위즐리 찰리 위즐리 조지 위즐리 아서 위즐리 지니 위즐리 빌 위즐리
자바스크립트
ECMAScript 6의 일부인 JavaScript는 다음을 제공하는 모든 개체에서 반복기 패턴을 지원합니다.next()
method - 두 가지 특정 속성을 가진 개체를 반환합니다.done
그리고.value
다음은 리버스 어레이 리터레이터의 예를 제시하겠습니다.
기능. reverseArrayIterator(배열) { 변화하다 색인 = 배열.길이 - 1; 돌아가다 { 다음 분.: () => 색인 >= 0 ? {가치: 배열[색인--], 다 했어요.: 거짓의} : {다 했어요.: 진실의} } } 컨스턴트 그것 = reverseArrayIterator(['3', '둘', '하나]); 콘솔.로그.(그것.다음 분.().가치); //-> '하나' 콘솔.로그.(그것.다음 분.().가치); //-> '2' 콘솔.로그.(그것.다음 분.().가치); //-> '3' 콘솔.로그.("다 썼어? ${그것.다음 분.().다 했어요.}`); //-> 참
단, 대부분의 경우 오브젝트에 반복적인[6] 의미를 부여하여 오브젝트를 자동으로 반복할 수 있도록 하는 것이 바람직합니다.for...of
루프. JavaScript의 기본 제공 유형 중 일부는 다음과 같습니다.Array
,Map
, 또는Set
는, 독자적인 반복 동작을 이미 정의하고 있습니다.개체의 메타를 정의하여 동일한 효과를 얻을 수 있습니다.@@iterator
메서드, 에 의해 참조되기도 합니다.Symbol.iterator
그러면 반복 가능한 개체가 생성됩니다.
다음으로 시작하는 값 목록을 생성하는 범위 함수의 예를 나타냅니다.start
로.end
, 배타적, 통상의 사용for
loop을 사용하여 번호를 생성합니다.
기능. 범위(개시하다, 끝.) { 돌아가다 { [기호..리터레이터]() { // #A 돌아가다 이것.; }, 다음 분.() { 한다면 (개시하다 < > 끝.) { 돌아가다 { 가치: 개시하다++, 다 했어요.: 거짓의 }; // #B } 돌아가다 { 다 했어요.: 진실의, 가치: 끝. }; // #B } } } 위해서 (번호 의 범위(1, 5)) { 콘솔.로그.(번호); // -> 1, 2, 3, 4 }
문자열과 같은 삽입 유형의 반복 메커니즘도 조작할 수 있습니다.
허락하다 반복하다 = ['나', 't', 'e', 'r, 'a', 't', o, 'r][기호..리터레이터](); 반복하다.다음 분.().가치; //-> I 반복하다.다음 분.().가치; //-> t
PHP
PHP는 표준 [7]배포의 일부로 반복기 인터페이스를 통해 반복기 패턴을 지원합니다.인터페이스를 실장하는 오브젝트는 를 사용하여 반복할 수 있습니다.foreach
언어 구성
PHP를 사용한 패턴의 예:
<?개요 // BookIterator.php 네임스페이스 디자인 패턴; 학급 북이터레이터 용구 \Iterator { 사적인 인트 $i_포지션 = 0; 사적인 북컬렉션 $books 컬렉션; 일반의 기능. __개요(북컬렉션 $books 컬렉션) { $ this->서적 수집 = $books 컬렉션; } 일반의 기능. 현재의() { 돌아가다 $ this->서적 수집->getTitle(제목)($ this->i_위치); } 일반의 기능. 열쇠(): 인트 { 돌아가다 $ this->i_위치; } 일반의 기능. 다음 분.(): 무효 { $ this->i_위치++; } 일반의 기능. 되감다(): 무효 { $ this->i_위치 = 0; } 일반의 기능. 유효한(): 부울 { 돌아가다 !is_filename(이것들)($ this->서적 수집->getTitle(제목)($ this->i_위치)); } }
<?개요 // Book Collection.php 네임스페이스 디자인 패턴; 학급 북컬렉션 용구 \Iterator Aggregate { 사적인 배열 $a_120 = 배열(); 일반의 기능. getIterator() { 돌아가다 신규 북이터레이터($ this); } 일반의 기능. add Title(제목 추가)(스트링 $string): 무효 { $ this->a_discloss.[] = $string; } 일반의 기능. getTitle(제목)(키) { 한다면 (세트($ this->a_discloss.[키])) { 돌아가다 $ this->a_discloss.[키]; } 돌아가다 무효; } 일반의 기능. is_empty(): 부울 { 돌아가다 빈($ this->$a_120); } }
<?개요 // index.interface 요구하다 '자동 로드'php'; 사용하다 DesignPatterns\BookCollection; $books 컬렉션 = 신규 북컬렉션(); $books 컬렉션->add Title(제목 추가)('디자인 패턴'); $books 컬렉션->add Title(제목 추가)('PHP7 최고'); $books 컬렉션->add Title(제목 추가)('라벨 규칙'); $books 컬렉션->add Title(제목 추가)('DHH 규칙'); 앞지르다 ($books 컬렉션 ~하듯이 $book) { var_var_var_module(변수)($book); }
산출량
string(15) "Design Patterns" string(16) "PHP7 is the best" string(13) "Laravel Rules" string(9) "DHH Rules"
파이썬
Python은 언어 자체의 일부로 반복자를 위한 구문을 규정하여 다음과 같은 언어 키워드를 제공합니다.for
Python이 말하는 'iterables'로 작업합니다.반복할 수 있는 사람은__iter__()
반복기 개체를 반환하는 메서드입니다."반복 프로토콜"은next()
다음 요소를 반환하거나 상승시키는StopIteration
예외로 설정합니다.반복기는 또한__iter__()
반복할 수 있도록 자신을 되돌리는 방법. 예를 들어, 예를 들어,for
2.2부터 발전기를 사용할 수 있습니다.
Python 3에서는next()
이름이 변경되었습니다.__next__()
를 클릭합니다.[8]
라쿠
Raku는 언어 자체의 일부로서 반복할 수 있는 오브젝트를 위해 반복자를 위한 API를 제공합니다.for
및 관련 반복 구성(예: 에 대한 할당)Positional
변수입니다.[9][10]반복할 수 있는 사람은 적어도 다음을 구현해야 합니다.iterator
반복기 개체를 반환하는 메서드입니다."반복 프로토콜"은pull-one
가능한 경우 다음 요소를 반환하거나 sentinel 값을 반환하는 메서드IterationEnd
값을 더 이상 산출할 수 없는 경우.반복 API는 다음과 같이 구성되어 있습니다.Iterable
역할.Iterator
또는 둘 다 및 필요한 메서드를 구현합니다.
유형 개체 또는 개체 인스턴스가 반복 가능한지 확인하려면does
다음 방법을 사용할 수 있습니다.
say Array.does (Itable); #=> True say [1, 2, 3]does (Itable); #=> True say Str.does (Itable); #=> False say "Hello" (Itable); #=> False say
그does
메서드 반환True
호출자가 인수 유형에 적합한 경우에만 해당됩니다.
예를 들어 다음과 같습니다.range
Python의 것을 모방한 서브루틴range
기능:
멀티{m{(수업{또한 Iterable, Iterator 하시니(달러 .start달러.end달러.step Int다);!상속!시작하고 법 반복기{자아달러달러 Int다}법 pull-one(-->Mu){만약달러!수>달러!끝 range(Int:D달러 시작, Int:D달러 끝 어디*<>)달러 시작, Int:D달러 단계에서*<0)))에스파냐달러 나는!달러 정도 couNt달러!수!이다;달러 나는 돌아오;}일 경우 다른{달러!상속달러!시작하 대가 IterationEnd.}}}).new(28달러에서 시작되었지만:달러가 끝나면:달러 단계)}멀티 range(Int:D달러 시작, Int:D달러 끝 어디*>)달러 시작, Int:D달러 단계에서*>0=1){(클래스{으로서의달러 +=.십니까Iterable, Int(달러.start달러.end달러.step),!상속달러 Int다!시작하고 법 반복기{자아}법 pull-one(-->Mu){만약달러!수<>달러!끝{내달러 나는 갈달러!수;달러!수 +=달러!단계 돌아가달러 거야.} 다른{Iterator달러는 않는다. 달러!cout = $!start; return RepeatingEnd; } } }.new(:$start, :$end, :$step) } my \x = range(1, 5), .say는 x, #OUTPUT: #1 #2 #3 #4는 x.map*.sum, #30 my = range1, 5는 y, say)입니다.
「 」를 참조해 주세요.
레퍼런스
- ^ Erich Gamma; Richard Helm; Ralph Johnson; John Vlissides (1994). Design Patterns: Elements of Reusable Object-Oriented Software. Addison Wesley. pp. 257ff. ISBN 0-201-63361-2.
- ^ "The Iterator design pattern - Problem, Solution, and Applicability". w3sDesign.com. Retrieved 2017-08-12.
- ^ 갱 오브 포
- ^ "The Iterator design pattern - Structure and Collaboration". w3sDesign.com. Retrieved 2017-08-12.
- ^ "C# foreach statement".
- ^ "Iterators and generators". Retrieved 18 March 2016.
- ^ "PHP: Iterator". Retrieved 23 June 2013.
- ^ "Python v2.7.1 documentation: The Python Standard Library: 5. Built-in Types". Retrieved 2 May 2011.
- ^ "Raku documentation: role Iterable". Retrieved 9 December 2020.
- ^ "Raku documentation: role Iterator". Retrieved 9 December 2020.
외부 링크
