Help us understand the problem. What is going on with this article?

Swiftでデザインパターン シングルトンパターン

More than 1 year has passed since last update.

シングルトンデザインパターン

  • 一番有名なデザインパターンなのではないでしょうか。
  • 普通、クラスはインスタンス化するごとに、別のインスタンスになるが、シングルトンパターンを使うと、インスタンスが常にひとつのものを利用されることを保証されます
  • Xcode上でも、iOS開発の際にUserDefaultsやURLSessionインスタンスにアクセスすることができますが、それらはシングルトンであり、どこからアクセスしても同じインスタンスが返ってきます
  • 賛否両論のパターンだと思われます
  • 新人だったら先輩に利用して良いか聞くべきかもしれません(あとで設計に関して怒られるかも)

メリット

  • メモリを節約できる
  • 別の画面でグローバルに使いたい場合
  • インスタンスを一つしか使わせたくない場合
  • データの不整合や、ファイルアクセスなどをするようなクラスを利用する場合は、毎回インスタンス化していると時間がかかるため使える

デメリットとアンチパターン

  • シングルトンのインスタンスの状態は管理しづらい(どこで状態が変わるかわからないため)
    • シングルトンは状態を持たず、副作用を持たないようにしたほうがよい
    • 状態を持たないほうが、テストも簡単
  • ファイルアクセスなどを専有したりすると、障害の元になる
  • テストしづらい
  • アプリ終了時にシングルトンが開放されるが、複数あった場合、開放のタイミングが不明
  • ただのグローバル変数になっているものもある
  • スレッドセーフ(複数のスレッドで同時に実行しても安全)であるような設計になってない(他の場所で同じインスタンスにアクセスすると落ちるとか障害の元になるときがある)

グローバル変数との違い

  • グローバル変数としてだけ実装していると、別にインスタンス化できてしまう
class GlobalVariable {}
let global = GlobalVariable()
let global2 = GlobalVariable()
// 一つのインスタンスとしての利用が保証されていない!
// 名前空間を汚染してしまう

実装方法のポイント2つ

  • 他のクラスからインスタンス化できないこと
  • アクセスするメソッドが提供されていること
class FileAccessManager {

    private static let sharedInstance: FileAccessManager = {
        return FileAccessManager(filePath: FileAccessManager.initialFilePath)
    }()

    private static let initialFilePath: String = "var/www/path"
    private let filePath: String

    private init(filePath: String) {
        self.filePath = filePath
    }

    class func shared() -> FileAccessManager {
        return self.sharedInstance
    }

    func fetchContent() {
        print(self.filePath)
    }
}

let manager = FileAccessManager.shared()
manager.fetchContent()

// 私見ですが、あらゆるところで使うというよりは、ある特定の場所でしか使わないほうが良いと思います
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away