Help us understand the problem. What is going on with this article?

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

今回参考にさせていただいた書籍です
増補改訂版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で書き起こしをしてみましたが、いろいろ勉強になることがあったので、他のパターンでもやってみようと思います。改善点などがあれば教えていただけると助かります。

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away