Golang에서 디자인 패턴 "Iterator"를 배웁니다.

14979 단어 5디자인 패턴GoF
GoF의 디자인 패턴을 학습하는 소재로서, 서적 「 증보 개정판 Java 언어로 배우는 디자인 패턴 입문 」가 참고가 되는 것 같네요.
다루어진 예제는 자바 기반이기 때문에 파이썬에서 동등한 사례에 도전한 적이 있었습니다.
Qiita 기사 : "Python에서 디자인 패턴 "Iterator"를 배우십시오"

이번에는 Python으로 구현한 "Iterator"의 샘플 앱을 Golang에서 다시 구현해 보았습니다.

■ Iterator(이터레이터 패턴)



Iterator 패턴(이터레이터 패턴)은 GoF(Gang of Four; 4명의 갱들)에 의해 정의된 디자인 패턴의 하나이다. 컨테이너 객체의 요소를 열거하는 수단을 독립적으로함으로써 컨테이너의 내부 사양에 의존하지 않는 반복자를 제공하는 것을 목적으로한다.

UML class and sequence diagram





UML 클래스 diagram




(이상 위키피디아(Wikipedia)에서 인용)

□ 비망록



Iterator 패턴이란, 무언가가 많이 모여 있을 때, 그것을 차례로 가리키고 가서, 전체를 스캔해 가는 처리를 실시하기 위한 것이라고 합니다. Iterator 는, 일본어로, 반복자라고 불리는 일도 있다고 합니다.
Python 프로그래밍에 종사하고 있다면 잘 보는 사람입니다.

■ "Iterator" 샘플 프로그램



실제로, Iterator 패턴을 활용한 샘플 프로그램을 움직여 보고, 다음과 같은 동작의 모습을 확인하고 싶습니다.
  • 책장에 Aroun d the World in 80 days 책 추가
  • 책장에 Bible 책 추가
  • 책장에 Cinderella 책 추가
  • 책장에 Daddy-Long-Legs 책 추가
  • 현재 책장에있는 책의 제목을 표시합니다
  • $ go run Main.go 
    Aroun d the World in 80 days
    Bible
    Cinderella
    Daddy-Long-Legs
    

    ■ 샘플 프로그램에 대해 자세히 알아보기



    Git 저장소에도 비슷한 코드가 있습니다.
    htps : // 기주 b. 이 m / 싹 보 / s dy _ f_로 해 응 _ 파테 r
  • 디렉토리 구성
  • .
    ├── Main.go
    └── iterator
        ├── aggregate.go
        ├── book.go
        └── iterator.go
    

    (1) Iterator(반복자)의 역



    요소를 차례로 스캔해 가는 인터페이스를 정하는 역할입니다.
    샘플 프로그램에서는, Iterator 인터페이스가, 이 역할을 노력합니다.

    iterator/iterator.go
    package iterator
    
    // Iterator is interface
    type Iterator interface {
        HasNext() bool
        Next() *Book
    }
    

    (2) ConcreteIterator(구체적인 반복자)의 역할


    Iterator 역할로 정한 인터페이스를 실제로 구현하는 역할입니다.
    샘플 프로그램에서는, bookShelfIterator 구조체가, 이 역할을 노력합니다.
    이 역할에는 스캔하는 데 필요한 정보가 있어야 합니다.
    샘플 프로그램에서는 BookShelf 구조체의 인스턴스를 멤버 변수 bookShelf 로 기억하고, 주목하고 있는 책을 멤버 변수 index 로 기억하게 되어 있습니다.

    iterator/book.go
    type bookShelfIterator struct {
        bookShelf *BookShelf
        index     int
    }
    
    func newBookShelfIterator(bookShelf *BookShelf) *bookShelfIterator {
        return &bookShelfIterator{
            bookShelf: bookShelf,
            index:     0,
        }
    }
    
    // HasNext func for checking condition
    func (b *bookShelfIterator) HasNext() bool {
        if b.index < b.bookShelf.getLength() {
            return true
        }
        return false
    }
    
    // Next func for fetching book
    func (b *bookShelfIterator) Next() *Book {
        book := b.bookShelf.getBookAt(b.index)
        b.index++
        return book
    }
    

    (3) Aggregate(집합체)의 역할


    Iterator 역을 만들어 내는 인터페이스를 정하는 역입니다. 그 인터페이스는, 「내가 가지고 있는 요소를 차례로 스캔해 주는 사람」을 만들어 내는 추상화 메소드라고 하는 것이 됩니다.
    샘플 프로그램에서는, Aggregate 인터페이스가, 이 역할을 노력합니다.

    iterator/aggregate.go
    package iterator
    
    // Aggregate is interface
    type Aggregate interface {
        Append(book *Book)
        Iterator() Iterator
    }
    

    (4) ConcreteAggregate(구체적인 집합체)의 역할


    Aggregate 역할이 정한 인터페이스를 실제로 구현하는 역할입니다. 구체적인 Iterator 역할, 즉 ConcreteIterator 역할의 인스턴스를 만듭니다.
    샘플 프로그램에서는, BookShelf 구조체가, 이 역할을 노력합니다.

    iterator/book.go
    // BookShelf is struct
    type BookShelf struct {
        last  int
        books []*Book
    }
    
    // NewBookShelf func for initializing NewBookShelf
    func NewBookShelf() *BookShelf {
        return &BookShelf{
            last: 0,
        }
    }
    
    func (b *BookShelf) getBookAt(index int) *Book {
        return b.books[index]
    }
    
    // Append func for adding book
    func (b *BookShelf) Append(book *Book) {
        b.books = append(b.books, book)
        b.last++
    }
    
    func (b *BookShelf) getLength() int {
        return b.last
    }
    
    // Iterator func for iterating BookShelfIterator
    func (b *BookShelf) Iterator() Iterator {
        return newBookShelfIterator(b)
    }
    

    (5) Client(의뢰인)의 역할



    샘플 프로그램에서는 startMain 함수가 이 역할을 합니다.

    Main.go
    package main
    
    import (
        "fmt"
    
        "./iterator"
    )
    
    func startMain(bookShelf iterator.Aggregate) {
        bookShelf.Append(iterator.NewBook("Aroun d the World in 80 days"))
        bookShelf.Append(iterator.NewBook("Bible"))
        bookShelf.Append(iterator.NewBook("Cinderella"))
        bookShelf.Append(iterator.NewBook("Daddy-Long-Legs"))
        it := bookShelf.Iterator()
        for it.HasNext() {
            book := it.Next()
            fmt.Println(book.GetName())
        }
    }
    
    func main() {
        startMain(iterator.NewBookShelf())
    }
    

    (6) 기타



    책 제목을 관리합니다.

    iterator/book.go
    // Book is struct
    type Book struct {
        name string
    }
    
    // NewBook func for initializing Book
    func NewBook(name string) *Book {
        return &Book{
            name: name,
        }
    }
    
    // GetName func for getting bookname
    func (b *Book) GetName() string {
        return b.name
    }
    

    ■ 참고 URL


  • 파이썬에서 디자인 패턴 "Iterator"를 배우십시오.
  • 좋은 웹페이지 즐겨찾기