[iOS/Swift] アプリ開発の実務的アプローチで学ぶデザインパターン ~Decorator~


この記事シリーズは、iOS/Swiftエンジニアである執筆者個人が、
ごく普通のiOSアプリ開発でよくある状況
Swiftのコアライブラリやフレームワークで使われているパターン
着目してデザインパターンを学び直してみた記録です。

関連記事一覧
[iOS/Swift] アプリ開発の実務的アプローチで学ぶデザインパターン

Decoratorパターン概要

  • 継承を使わずに振る舞いやプロパティを付け足す手法です。
  • 実務で陥りがちな問題として、親クラス > 子クラス > 孫クラス のような継承のネスト構造では、孫クラスでの機能追加/変更が子クラス・親クラスまで影響してしまうことがあります。Decoratorパターンは、それを避けるための手法です。
  • Decorator(拡張する側)オブジェクトのコンストラクタでラップ対象のオブジェクトのインスタンスを受け取り、変数に保持して、それに対して新しい振る舞いやプロパティを追加(=Decorate)します。
  • 一段階Decorateしたオブジェクトをさらにもう一段階Decorateできる、という再帰的な構造も特徴です。
  • GoFのでデザインパターンでは構造に関するパターンに分類されます。

使い所

  • 正直、ごく普通のiOSアプリ開発での利用場面は思いつきませんでした。
  • Swiftには「継承を使わずに拡張する」ための言語機能としてextensionやprotocol extensionがありますし…
  • iOSの世界の一例としては、 NSAttributedString/NSMutableAttributedString がDecorateパターンになっています。

サンプルコード

Swiftバージョンは 5.1 です。

let attrStr = NSAttributedString(string: "Decoratorパターンのサンプルです",
                                 attributes: [.foregroundColor: UIColor.blue])
let mutableAttrStr = NSMutableAttributedString(attributedString: attrStr)
mutableAttrStr.setAttributes([.font : UIFont.systemFont(ofSize: 24.0)],
                             range: NSRange(location: 0, length: 13))
  • NSAttributedStringはStringのインスタンスを受け取り、変数に保持して、新しい振る舞いやプロパティを提供してくれます。
  • NSMutableAttributedStringはNSAttributedString(あるいはString)のインスタンスを受け取り、以下同文です。