Swiftで遊ぼう! on Hatena

あしたさぬきblogでやってた初心者オヤジのiOSプログラミング奮闘記がHatenaに来ました

Swiftで遊ぼう! - 431 - Swiftでデザインパターン 9 Facade(ファサード)

2016年12月1日:Swift 3に向けて改訂*1

最初のページに戻る -> Swiftで遊ぼう! - 423 - Swiftでデザインパターン まえがき - Swiftで遊ぼう! on Hatena

yataiblue.hatenablog.com

Introducing iOS Design Patterns in Swift – Part 1/2チュートリアルでシングルトンの実装をしたのですが、利用するにあたりファサードを理解する必要があるので、今回はファサード(Facade)の勉強をします。

ネットで検索して上位に出てきた 矢沢久雄の早わかりGoFデザインパターン - 矢沢久雄の早わかりGoFデザインパターン(4):ITpro を読みました。矢沢久雄さんの説明はわかりやすかったです。前半部分の前置きの内容も興味深く、オブジェクト指向プログラマーの考えるプログラムは「オブジェクトとメッセージ」という考え方のようです。まだピンと来ないけど、多数の細胞が結びついて1つの生体を作り上げるようにオブジェクトが集まり、メッセージングを通じて1つのプログラムができる感じです。

リアルな細胞のメッセージングは複雑で、「生命」の根源を知るくらい難解なことですが、オブジェクト指向のメッセージングは、GoFの23パターンが基本と考えれば、オブジェクト指向も単純だと思えます(^^)/

オブジェクトを意識しながらコーディングの勉強をしていきます。

オブジェクト指向における再利用のためのデザインパターン

オブジェクト指向における再利用のためのデザインパターン

ファサード・パターン

早速クラス図を眺めてみます。

f:id:yataiblue:20150902234718j:plain

色々な目的のためにクラスA、クラスB、クラスCを作ったけど、それを利用するためにそれぞれのクラス個別に仕様するのでは無く、様々なクラス利用をまとめてしまうクラスをファサード・クラスといいます。個別のクラスの使用法を知らなくても、ファサード・クラスの利用法だけ知っていればいいのでかなり便利です。

しかし、ファサードデザインパターンはクラス記述のために決められたルールは無いのでこのチュートリアルで説明します。

シングルトン・パターンで実装したLibraryAPIクラスをファサード・パターンとして使用できるようにします。

制御するクラスをプライベートのプロパティとして持たせます。

    private let persistencyManager: PersistencyLibrary
    private let httpClient: HTTPClient
    private let isOnline: Bool

「isOnline」は外部サーバー(URLRequestを使って)にアクセスするかどうか判定するプロパティです。

そしてシングルトンのイニシャライザでプロパティのインスタンス化ができるようにします。

    private override init(){
        persistencyManager = PersistencyLibrary()
        httpClient = HTTPClient()
        isOnline = false
        
        super.init()
    }

ファサード・モデルの神髄は、このクラスに実装するメソッドを使って、persistencyManagerクラスのメソッドを呼ぶということです。なにも考えていないと二度手間に見えます。しかし、絡み合うクラスが多数で複雑になれば必要な機能のみを提供するファサード・パターンは便利になります。実はiOSフレームワークの仕組みは当にファサードが多用されているんです。

    func getAlbums() -> [Album] {
        return persistencyManager.getAlbums()
    }
    
    func add(album: Album, index: Int) {
        persistencyManager.addAlbum(album: album, index: index)
        if isOnline {
            httpClient
        }
    }
    
    func deleteAlbum(index: Int) {
        persistencyManager.deleteAlbumAt(index: index)
        if isOnline {
            httpClient
        }
    }

ファサードの真骨頂は、add()メソッドのように、persistencyManagerに実装したメソッドを拡張できる点です。状態を判定する仕組みは元のメソッドにはありません。このように更にメソッドを使いやすくさせる目的がファサードです。

yataiblue.hatenablog.com

*1:2015年12月5日改訂:デザインパターンの復習をしています。