LoginSignup
4

More than 3 years have passed since last update.

IteratorパターンをSwiftで書いてみた

Posted at

今回参考にさせていただいた書籍です
増補改訂版Java言語で学ぶデザインパターン入門

protocolの実装

iterator.swift
protocol Iterator {
    associatedtype Item
    var hasNext: Bool { get }
    func next()->Item
}

iteratorはaggregateから生成されて、配列を数え上げるprotocolです。

aggregate.swift
protocol Aggregate {
    associatedtype IteratorImpl: Iterator
    var iterator: IteratorImpl { get }
}

aggregateは対応したiteratorを返します。

実装クラスの実装

book.swift
class Book {
    let name: String
    init(name: String) {
        self.name = name
    }
}

数え上げられるItemです。

bookshelf.swift
class BookShelf: Aggregate {
    typealias IteratorImpl = BookShelfIterator
    var len: Int {
        return books.count
    }
    private(set) var books: [Book] = []
    var iterator: BookShelfIterator {
        return BookShelfIterator(self)
    }

    func appendBook(book: Book) {
        self.books.append(book)
    }
}

Aggregateの実装クラスです。
書籍の方では取得するために、getBookAt(index:Int)で本を取得してましたが、private(set) varで十分だと思い今回は実装していません。

bookiterator.swift
class BookShelfIterator: Iterator {
    typealias Item = Book

    private let shelf: BookShelf
    private var index: Int

    var hasNext: Bool {
        if index < shelf.len {
            return true
        } else {
            return false
        }
    }

    init(_ shelf: BookShelf) {
        self.shelf = shelf
        self.index = 0
    }

    func next() -> Book {
        defer {
            self.index += 1
        }
        return self.shelf.books[self.index]
    }
}

BookShelfIteratorは書籍の方と同じです。

呼び出し

main.swift
var shelf = BookShelf()
shelf.appendBook(book: Book(name: "Code Complete"))
shelf.appendBook(book: Book(name: "Design Pattern"))
shelf.appendBook(book: Book(name: "Clean Architecture"))
var iterator = shelf.iterator
while (iterator.hasNext) {
    print(iterator.next().name)
}

呼び出しに関してはほぼ書籍通りになってますが、個人的にiteratorから帰ってくる値がAnyもしくはAnyObjectが嫌だったので、associatedtypeを使って実装クラスで返す値の型とiteratorの型を決定しています。

なのでmain.swiftに書かれてるiteratorはiteratorに準拠したクラスになるため、iteratorのhasNextnext()を呼んでいるというより、iteratorに準拠したhasNextnext()を呼んでいることになります。

勉強がてらデザインパターンをSwiftで書き起こしをしてみましたが、いろいろ勉強になることがあったので、他のパターンでもやってみようと思います。改善点などがあれば教えていただけると助かります。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4