【GoF】23種類のデザインパターンとは?Swiftでよく使う活用例

【GoF】23種類のデザインパターンとは?Swiftでよく使う活用例

この記事からわかること

  • GoFデザインパターンとは?
  • 23種類概要違い
  • Swift(iOS)で活用されているパターンは?
  • シングルトンDelegateObserver実例

index

[open]

\ アプリをリリースしました /

みんなの誕生日

友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-

posted withアプリーチ

アプリケーションなどのソフトウェア開発における設計知識として「GoF」の「デザインパターン」についてまとめて行きます。

GoFのデザインパターンとは?

GoFのデザインパターンとはオブジェクト指向ソフトウェアの設計に関する知見やノウハウに再利用性しやすいようにまとめたものです。

これは1994年にErich Gamma、Richard Helm、Ralph Johnson、John Vlissidesの4人の著者によって出版された、「Design Patterns: Elements of Reusable Object-Oriented Software」という書籍に記載された23種類のソフトウェアデザインパターンとして初めて世の中に公開されました。その4人のことをまとめてGoF(Gang of Four)と呼ばれています。

デザインパターンはオブジェクト指向型のプログラミング言語を使用したソフトウェア開発において基本的な考え方や設計原則を表現したものです。そのため今でもJavaやC#、Python、Ruby、Swiftなど数多くのオブジェクト指向型のプログラミング言語で活用されています。

しかし言語やプラットフォームによってデザインパターンの具体的な実装方法や適用範囲が異なる場合が多いので特定の言語やプラットフォームに依存せず、一般的な設計原則を理解し、柔軟な設計を行うことが重要です。

23種類のデザインパターン

ざっと23種類存在するデザインパターンを見てみましょう。これらは大きく分けて「生成に関するパターン」、「構造に関するパターン」、「振る舞いに関するパターン」の3つのカテゴリに分かれています。

生成に関するパターン

デザインパターン名 概要
Abstract Factory 関連する複数のオブジェクト群を作成する抽象ファクトリを定義し、実際の作成は具象ファクトリで行う。
Builder 複雑なオブジェクトを生成するために、生成過程を分解し、一つずつオブジェクトを生成するビルダーを使用する。
Factory Method オブジェクトを生成するための抽象ファクトリを定義し、具象ファクトリを実装することで、オブジェクトの生成方法をカプセル化する。
Prototype クラスのインスタンスを使用して、新しいオブジェクトを複製することで生成を行う。
Singleton システム内で唯一のインスタンスを保証することで、グローバルなオブジェクトの生成を行う。

構造に関するパターン

デザインパターン名 概要
Adapter 互換性のないオブジェクト間でインターフェースを変換するためのアダプタを作成する。
Bridge 抽象的な概念と具体的な実装を分離することで、柔軟な構造を作成する。
Composite オブジェクトをツリー構造で階層的に組み合わせ、単一のオブジェクトとして扱えるようにする。
Decorator オブジェクトに対して機能を追加するためのデコレータを作成する。
Facade 複数のオブジェクトを一つの単純なインターフェースにまとめ、システムを簡略化する。
Flyweight 重複して生成されるオブジェクトを共有して使用することで、メモリ使用量を削減する。
Proxy オブジェクトに対するアクセスを制御するためのプロキシを作成する。

振る舞いに関するパターン

デザインパターン名 概要
Chain of Responsibility 複数のオブジェクトをチェーン状に組み合わせ、一つのオブジェクトから他のオブジェクトに順次処理を渡す。
Command 要求をオブジェクトとしてカプセル化し、それらを操作することで、アンドゥ、リドゥなどの操作を実現する。
Interpreter 文法規則を定義し、それに基づいて入力を解釈するためのインタプリタを作成する。
Iterator オブジェクトの要素に順番にアクセスするためのイテレータを作成する。
Mediator 複数のオブジェクト間で中央的な仲介役を持ち、相互作用を行うようにする。
Memento オブジェクトの状態を保存し、必要に応じてその状態を復元する。
Observer オブジェクトの状態変化を監視し、状態が変化した場合に依存オブジェクトに通知する。
State オブジェクトの状態に応じて振る舞いを変化させることで、柔軟な振る舞いを実現する。
Strategy アルゴリズムの集合を定義し、必要に応じてアルゴリズムを切り替えることで、柔軟な振る舞いを実現する。
Template Method アルゴリズムの骨子を定義し、具体的な処理をサブクラスで実装することで、柔軟な振る舞いを実現する。
Visitor 複数のクラスを訪問する処理を一つのクラスにまとめることで、新しい操作を追加しやすくする。

Swiftの設計で見るデザインパターン

Swiftでもデザインパターンがさまざまな箇所で活用されています。Swiftでの実例を見ながらよく使われているパターンの概要を整理しておきます。

Singletonパターン

Singleton(シングルトン)パターンはクラスインスタンスを1つしか生成しないデザインパターンです。これによりアプリ全体で共通したデータを扱うことができるようになっています。

SwiftではUIApplicationUserDefaultsなどでシングルトンインスタンスが活用されています。実際にはクラスのプロパティに自身のインスタンスを格納し、そのプロパティを常に参照することで同じインスタンスを保証させます。

UIApplication.shared
UserDefaults.standard

なのでシングルトンは簡単にオリジナルクラスに組み込むことが可能です。

class UserModel {
    // シングルトンとなるようにsharedプロパティを定義
    public var shared = UserModel()
}

MVCパターン

アーキテクチャとして知られるMVCもデザインパターンの1種です。プログラムの役割をView、Controller、Modelの3つに分割して設計するパターンであり、SwiftにおいてはUIKitフレームワークがMVCアーキテクチャに基づいているようです。

おすすめ記事:Swift(UIKit)のMVCアーキテクチャーとは?役割と構造まとめ

Delegateパターン

Delegate(デリゲート)パターンとは日本語で「委任/委譲」を意味する名前の通り、処理を委譲するためのデザインパターンです。 処理の委譲はオブジェクト間で行われます。SwiftにおけるDelegateの詳細は以下の記事を参考にしてください。

おすすめ記事:【Swift】delegate(デリゲート)とは?使い方とメリット

SwiftではApp DelegateUITableViewDelegateなどがDelegateパターンに倣った処理の委任が組み込まれています。

 class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    }
}

Observerパターン

Observer(オブザーバー)パターンは日本語で「観測」を意味する通り、オブジェクトの状態を観測し、それに応じてオブジェクトを更新するデザインパターンです。対象となる2つのオブジェクトがあり「観測される側(Subject)」と「観測する側(Observer)」に分かれます。(Subjectは被写体といった意味です)

SwiftではNotificationCenterKVO(Key-Value Observing)を利用してオブジェクトの状態変化を監視することができます。またRXSwiftなどでも活用されています。

おすすめ記事:【GoF】Observerパターンとは?Publish-Subscribeパターンとの違い

Factory Methodパターン

Factory Methodパターンはオブジェクトの生成を担当するFactoryクラスを介して、オブジェクトの生成を行うデザインパターンです。

SwiftではUIKitにおけるViewの生成(UIViewクラスのサブクラスのインスタンス化)にFactory Methodが使われています。

おすすめ記事:【Swift/UIKit】UIViewクラスとは?使い方やプロパティまとめ

// UIViewクラスはインスタンス化時にサブクラスのインスタンスを生成するためのファクトリメソッドとしてinit(frame:)メソッドを提供している
let label = UILabel(frame: CGRect(x: 0, y: 0, width: 100, height: 50))

まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。

ご覧いただきありがとうございました。

searchbox

スポンサー

ProFile

ame

趣味:読書,プログラミング学習,サイト制作,ブログ

IT嫌いを克服するためにITパスを取得しようと勉強してからサイト制作が趣味に変わりました笑
今はCMSを使わずこのサイトを完全自作でサイト運営中〜

New Article

index