goat’s village(wonderful IT life)

IT でエンジニア人生謳歌しちゃう村

Iterator パターンを Swift で書き換えてみた

Java で書かれていたサンプルコードを、Swift で書き換えてみた。

/// アグリゲートの役
protocol Aggregate {
    func iterator() -> Iterator
}

/// イテレータの役
protocol Iterator {
    func hasNext() -> Bool
    func next() -> Any
}

/// 本を取り出す実体
final class Book {
    private let name: String
    init(name: String) {
        self.name = name
    }
    func getName() -> String {
        return self.name
    }
}

/// コンクリート・アグリゲートの役
final class BookShelf: Aggregate {
    private var books: [Book] = []
    private var last: Int = 0
    
    func getBookAt(index: Int) -> Book {
        return self.books[index]
    }
    
    func appendBook(book: Book) {
        self.books.append(book)
        self.last += 1
    }
    
    func getLength() -> Int {
        return self.last
    }
    
    func iterator() -> Iterator {
        return BookShelfIterator(bookShelf: self)
    }
}

/// コンクリート・イテレータの役
final class BookShelfIterator: Iterator {
    private var bookShelf: BookShelf
    private var index: Int
    
    init(bookShelf: BookShelf) {
        self.bookShelf = bookShelf
        self.index = 0
    }
    
    func hasNext() -> Bool {
        if self.index < self.bookShelf.getLength() {
            return true
        } else {
            return false
        }
    }
    
    func next() -> Any {
        let book = self.bookShelf.getBookAt(index: index)
        self.index += 1
        return book
    }
}

/// メイン
let bookShelf = BookShelf()
bookShelf.appendBook(book: Book(name: "テスト"))
bookShelf.appendBook(book: Book(name: "サンプル"))
bookShelf.appendBook(book: Book(name: "テストサンプル"))
bookShelf.appendBook(book: Book(name: "example"))
var it = bookShelf.iterator()
while it.hasNext() {
    let book = it.next() as! Book
    print((book.getName()))
}

参考文献 www.amazon.co.jp

Swift で Adapter パターンを書いてみる

オブジェクト指向の勉強でデザインパターンの勉強をしております。 Java で書かれてるコードを Swift で書き換えます。

継承、委譲のパターンがあるようなのでそれぞれ記載。

まずは継承パターンから。

// ターゲット
protocol Print {
    func printWeak()
    func printStrong()
}
// アダプティー(元々用意されているもの)
class Banner {
    
    private let string: String
    
    init(string: String) {
        self.string = string
    }
    
    func showWithParen() {
        print("(" + string + ")")
    }
    
    func showWithAster() {
        print("*" + string + "*")
    }
}
// アダプターの役(このクラスに適合させる)
class PrintBanner: Banner, Print {
    func printWeak() {
        showWithParen()
    }
    
    func printStrong() {
        showWithAster()
    }
}
// クライアント
let p = PrintBanner(string: "Hello")
p.printWeak()
p.printStrong()

実行結果

(Hello)
*Hello*

委譲パターン

// ターゲット
protocol Print {
    func printWeak()
    func printStrong()
}
// アダプティー(元々用意されているもの)
class Banner {
    
    private let string: String
    
    init(string: String) {
        self.string = string
    }
    
    func showWithParen() {
        print("(" + string + ")")
    }
    
    func showWithAster() {
        print("*" + string + "*")
    }
}
// アダプター
class PrintBanner: Print {
    let banner: Banner
    
    init(string: String) {
        self.banner = Banner(string: string)
    }
    
    func printWeak() {
        banner.showWithParen()
    }
    
    func printStrong() {
        banner.showWithAster()
    }
}
// クライアント
let p = PrintBanner(string: "Hello")
p.printWeak()
p.printStrong()

実行結果

(Hello)
*Hello*

Swift は extension で 「Swift らしく」書けるようなので、そちらも。

// ターゲット
protocol Print {
    func printWeak()
    func printStrong()
}
// アダプティー(元々用意されているもの)
class Banner {
    
    private let string: String
    
    init(string: String) {
        self.string = string
    }
    
    func showWithParen() {
        print("(" + string + ")")
    }
    
    func showWithAster() {
        print("*" + string + "*")
    }
}
extension Banner: Print {
    func printWeak() {
        showWithParen()
    }
    
    func printStrong() {
        showWithAster()
    }
}
// クライアント
let p = Banner(string: "Hello")
p.printWeak()
p.printStrong()

実行結果

(Hello)
*Hello*

extension が一番スマートな気もするが......。 まだなんとなく書いている感が抜けんなー。 引き続き勉強していこう。

参考

www.amazon.co.jp