[Swift]「シングルトン」

この記事では、シングルトンパターンの具体的な実装手順、依存性注入との比較、活用事例までまでを解説します。

目次

シングルトンの基礎

シングルトンは、特定のクラスのインスタンスがプログラム全体で唯一のものとなるようにするパターンです。
これにより、アプリケーション内でデータや状態を共有する効果的な手段となります。

シングルトンの実装方法

シングルトンを実装するためには、特定の手順を追う必要があります。以下の項目に沿って、シングルトンを実装するための手順を確認していきましょう。

STEP
シングルトンクラスの作成

最初に行うべき手順は、シングルトンクラスを作成することです。

class Singleton {
    static let shared = Singleton()
    
    private init() {
        // シングルトンクラスの初期化処理
    }
    
    // ここにシングルトンクラスのプロパティやメソッドを追加する
}
  1. 上記のコードでは、Singletonクラスにsharedという静的なプロパティを作成しています。
  2. そのプロパティを通じて唯一のインスタンスを取得できるようにしています。
  3. また、private init()というプライベートイニシャライザを定義することで、外部からのインスタンス化を制限しています。
STEP
シングルトンクラスの利用

シングルトンクラスを実装したら、他のクラスからシングルトンインスタンスにアクセスすることができます。

let singleton = Singleton.shared
// シングルトンインスタンスにアクセスして利用する
  1. 上記のコードでは、Singleton.sharedを通じてシングルトンインスタンスにアクセスしています。
  2. このように、他のクラスからシングルトンを利用する際には、sharedプロパティを介してアクセスします。

シングルトンと依存性注入

シングルトン依存性注入は、iOSアプリ開発において重要なトピックです。

依存性注入とは、あるクラス(受け手)が別のクラス(依存性)を必要とする場合に、その依存性を受け手に注入することを意味します。

依存性注入の実装方法

STEP
依存性注入するクラスの定義
class Dependency {
    // 依存性注入されるクラスの定義
}
  • Dependencyクラス: これは「依存性注入するクラス」を定義しています。
  • 具体的な内容はコメントで言及されていませんが、アプリケーションの特定の機能やデータを提供するクラスとして想定されます。
STEP
依存性注入を受けるクラスの定義
class SomeClass {
    let dependency: Dependency
    
    init(dependency: Dependency) {
        self.dependency = dependency
    }
    
    // ここにSomeClassのメソッドなどを追加する
}
  • SomeClassクラス: このクラスは依存性注入を受け入れるクラスです。
  • dependencyというプロパティは、Dependencyクラスのインスタンスを保持します。
  • initメソッドでは、dependencyを引数として受け取り、プロパティに代入しています。

この設計の意図は、SomeClassが外部から Dependency クラスのインスタンスを受け取ることで、異なる状況やテストをシミュレートすることが可能になります。

STEP
インスタンスの作成
// Dependencyクラスのインスタンスを作成
let dependencyInstance = Dependency() 

// SomeClassのインスタンスを作成
let someClassInstance = 
    SomeClass(dependency: dependencyInstance) 
  • このコードでは、まずDependencyクラスのインスタンスであるdependencyInstanceを作成します。
  • その後、SomeClassのイニシャライザを呼び出し、dependencyInstanceを引数として渡してsomeClassInstanceを作成します。
  • このとき、SomeClassは依存性としてdependencyInstanceを受け取り、その依存性を保持します。

シングルトンと依存性注入の比較

共通点
  1. インスタンスの一意性:
    特定のクラスのインスタンスを一意に制御することを目的としています。
  2. グローバルなアクセス:
    アプリケーション内の異なる箇所から簡単にアクセスできるようにする機能を提供します。
異なる点
  1. インスタンスの管理:
    シングルトン
    自身でインスタンスを生成し、グローバルにアクセス可能な唯一のインスタンスを提供します。
    依存性注入では外部からインスタンスを注入し、複数の異なるインスタンスを利用することができます。
  2. 柔軟性とテスト容易性:
    シングルトン
    は、グローバルにアクセスできる唯一のインスタンスを持つため、テスト時にモックオブジェクトの注入が困難になる場合があります。
    依存性注入は、異なる実装の依存性を注入することができ、柔軟な設計や単体テスト容易性を提供します。

テストでは、通常、モックオブジェクトと呼ばれる架空のオブジェクトを使用して依存関係を注入してテストを行います。しかし、シングルトンはグローバルなインスタンスを持つため、テスト時にモックオブジェクトを注入することが難しくなる場合があります。

シングルトンの活用事例

共有データの管理

以下のコード事例では、シングルトンを使用して共有データの管理を行います。

STEP
シングルトンクラスの作成
class DataManager {
    static let shared = DataManager()
    
    var sharedData: [String] = []
    
    private init() {}
    
    // 共有データの操作メソッドなどを追加する
}
  1. DataManagerクラス: このクラスはシングルトンデザインパターンを活用しています。
  2. sharedプロパティ:
    sharedは、アプリケーション内のどの場所からでもアクセス可能な静的なプロパティです。これにより、DataManager唯一のインスタンスにアクセスできます。
  3. sharedDataプロパティ:
    sharedDataは、データを保持するための配列です。この配列には文字列型のデータが格納されます。
  4. private init() {}:
    イニシャライザはprivateアクセス修飾子で宣言されており、外部からのインスタンス化を防ぐために隠蔽されています。
STEP
シングルトンクラスの利用
// データの追加
DataManager.shared.sharedData.append("Apple")
DataManager.shared.sharedData.append("Banana")
DataManager.shared.sharedData.append("Orange")

// データの表示
print(DataManager.shared.sharedData)
//["Apple", "Banana", "Orange"]
  • このコードでは、DataManager.shared を通じて DataManager クラスのシングルトンインスタンスにアクセスしています。
  • アクセスする際に .shared を使用することで、アプリケーション内のどの場所からでも同じインスタンスにアクセスできます。
  • データの追加は、sharedData 配列に .append メソッドを使って新しい要素を追加しています。
  • ここでは、”Apple”、”Banana”、”Orange” という文字列を追加しています。
  • データの表示は、print 文を使用して DataManager.shared.sharedData を出力しています。
  • これにより、sharedData 配列の内容が表示されます。

ユーザー設定の保存

ユーザー設定の保存にもシングルトンを活用することができます。

STEP
シングルトンクラスの作成
class UserSettings {
    static let shared = UserSettings()
    
    private let defaults = UserDefaults.standard
    
    var username: String? {
        get { return defaults.string(forKey: "Username") }
        set { defaults.set(newValue, forKey: "Username") }
    }
    
    private init() {}
    
    // 設定の操作メソッドなどを追加する
}
  • UserSettingsクラス:
    このクラスはシングルトンデザインパターンを用いて、ユーザー設定を管理します。
  • sharedプロパティ:
    sharedは、アプリケーション内のどの場所からでもアクセスできる静的なプロパティです。これにより、UserSettings唯一のインスタンスにアクセスできます。
  • defaultsプロパティ:
    defaultsは、UserDefaults.standard から生成される UserDefaults インスタンスです。
    このインスタンスを通じてユーザー設定を永続化(保存)します。
  • usernameプロパティ:
    usernameは、ユーザー名を格納するためのプロパティです。
  • get メソッドでは UserDefaults から "Username" キーを使用してユーザー名を取得します。
  • set メソッドではユーザー名を設定して UserDefaults に保存します。
STEP
シングルトンクラスの利用
// ユーザー名の設定
UserSettings.shared.username = "JohnDoe"

// ユーザー名の取得と表示
if let username = UserSettings.shared.username {
    print("ユーザー名: \(username)")
} else {
    print("ユーザー名は設定されていません。")
}
  1. このコードでは、UserSettings.shared を通じて UserSettings クラスのシングルトンインスタンスにアクセスしています。
  2. アクセスする際に .shared を使用することで、アプリケーション内のどの場所からでも同じインスタンスにアクセスできます。
  3. ユーザー名の設定は、UserSettings.shared.username を使用して行います。これにより、set メソッドが呼ばれてユーザー名が UserDefaults に保存されます。
  4. ユーザー名の取得は、UserSettings.shared.username を使用して行います。これにより、get メソッドが呼ばれて UserDefaults からユーザー名が取得されます。
  5. 取得したユーザー名が存在すれば、それを表示します。ユーザー名が設定されていない場合は、代わりに「ユーザー名は設定されていません。」と表示されます。

この記事が気に入ったら
いいね または フォローしてね!

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする

目次