シングルトンパターンを依存性注入と組み合わせて使用するにはどうすればよいですか?

iOShit私はめちゃくちゃ

最近、依存性注入を使用することが「今日のソフトウェア開発の世界でシングルトンを使用する唯一の社会的に受け入れられる方法」であると聞きました。この声明はほとんど意見に基づいているため、現時点でこの声明の正確性について必ずしも議論したくはありません。今の私の目標は、シングルトンパターンで依存性注入をどのように正確に使用できるを理解することです。

たとえば、最新のiOSアプリには、URLSessionコードを保持するサービスレイヤーがあります。このレイヤーをシングルトンとして作成しました。

struct ServiceSingleton {

    private init()

    static let shared = ServiceSingleton()

    func fetchJSON() {
     // URLSession code
    }

}

次に、以下のようsharedに、ViewController使用ます。

class ViewController: UIViewController() {

    override viewDidLoad() {
        super.viewDidLoad()

        fetchData()    

    }

    fileprivate func fetchData() {

        ServiceSingleton.shared.fetchJSON()
    }

}

もちろん、上記のコードはシングルトンを使用していますが、依存性注入は使用していません。一般に依存性注入を使用したい場合は、ViewControllerに次のようなものを追加することを認識しています。

// Dependency Injection Constructor
override init(someProperty: SomePropertyType) {
    self.someProperty = someProperty
    super.init()
}

TL; DR:

(1)Swiftでシングルトンパターンを使用して依存性注入を適切に使用する方法を教えてください。

(2)これが何を達成するのか説明してもらえますか?

(3)今後iOSプロジェクトでシングルトンパターンを使用する場合、常にDIを使用する必要がありますか?

アレクサンダー
  1. Swiftのシングルトンパターンで依存性注入を適切に使用する方法を教えてください。

    ServiceSingleton.shared直接アクセスするのではなく、オブジェクトに挿入されるインスタンス変数にアクセスします。通常は、可能であれば初期化子で、そうでない場合は初期化後に設定可能なプロパティとしてアクセスします。

    protocol FooService {
        func doFooStuff()
    }
    
    class ProductionFooService: FooService {
    
        private init() {}
    
        static let shared = ProductionFooService()
    
        func doFooStuff() {
            print("real URLSession code goes here")
        }
    
    }
    
    struct MockFooService: FooService {
        func doFooStuff() {
            print("Doing fake foo stuff!")
        }
    }
    
    class FooUser {
        let fooService: FooService
    
        init(fooService: FooService) { // "initializer based" injection
            self.fooService = fooService
        }
    
        func useFoo() {
            fooService.doFooStuff() // Doesn't directly call ProductionFooService.shared.doFooStuff
        }
    }
    
    let isRunningInAUnitTest = false
    
    let fooUser: FooUser
    if !isRunningInAUnitTest {
        fooUser = FooUser(fooService: ProductionFooService.shared) // In a release build, this is used.
    }
    else {
        fooUser = FooUser(fooService: MockFooService()) // In a unit test, this is used. 
    }
    
    fooUser.useFoo()
    

    通常、ViewControllerの初期化はストーリーボードによって行われるため、初期化パラメーターを介して依存関係を検出することはできず、代わりにオブジェクトの初期化後に設定される保存済みプロパティを使用する必要があります。

  2. これが何を達成するのか説明してもらえますか?

    コードはに結合されなくなりましたProductionFooService.sharedこの結果FooService、ベータ環境用の実装、単体テスト用のモック実装などさまざまな実装を導入できます

    すべてのコードが直接製品の依存関係を広く使用している場合は、...

    1. テスト環境でオブジェクトをインスタンス化することは不可能であることがわかります。単体テスト、CIテスト環境、ベータ環境などを製品データベース、サービス、APIに接続する必要はありません。

    2. 真の「ユニット」テストはありません。すべてのテストは、コードの単位に加えて、推移的に依存するすべての一般的な依存関係をテストします。これらの依存関係の1つにコード変更を加えると、システム内のほとんどの単体テストが失敗し、失敗したものを正確に特定することが困難になります。依存関係を分離することで、単体テストをサポートするために最低限必要なモックオブジェクトを使用し、各テストが依存する推移的な依存関係ではなく、特定のコード単位のみをテストするようにすることができます。

  3. 今後iOSプロジェクトでシングルトンパターンを使用する場合、常にDIを使用する必要がありますか?

    拾うのは良い習慣です。もちろん、速く移動したいだけであまり気にしないqucik-and-dirty-projectsもありますが、これらの想定されるqucik-and-dirty-projectsの多くが実際に離陸することに驚かれることでしょう。将来的に費用を支払う。あなたは自分の良識を切り離すために余分な時間をかけないことによって自分自身を妨げているときを認識する必要があります。

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

Azure Functionsでカスタムパラメーターバインディングと依存性注入を組み合わせるにはどうすればよいですか?

分類Dev

パターンとグラデーションを1つのパスに組み合わせるにはどうすればよいですか?

分類Dev

モジュール自体がコンストラクターとしてパラメーターを受け取る場合、依存性を注入するにはどうすればよいですか?

分類Dev

matplotlibボタンをアニメーション機能と組み合わせて使用するにはどうすればよいですか?

分類Dev

LUAでパターンマッチングを行うときに、単語と数字を組み合わせるにはどうすればよいですか?

分類Dev

Pythonでbase32をhotp(ワンタイムパスワード)と組み合わせて使用するにはどうすればよいですか?

分類Dev

ファサードパターンで依存性注入を使用するにはどうすればよいですか?

分類Dev

ポアソン回帰でグループを組み合わせてコントラストを推定するにはどうすればよいですか?

分類Dev

段落内でツールチップタグと段落マージンタグを組み合わせるにはどうすればよいですか?

分類Dev

調査データを操作しているときに、パンダの列を組み合わせるにはどうすればよいですか?

分類Dev

CPUとGPUグラフィックを組み合わせてパフォーマンスを向上させるにはどうすればよいですか?

分類Dev

カルカースカレンダーと組み合わせてnotify-sendコマンドを使用するにはどうすればよいですか?

分類Dev

継承と組み合わせてオブザーバーパターンを実現するにはどうすればよいですか?

分類Dev

プロパティのタイプとインスタンスがサードパーティパッケージの一部である場合、プラグインのプロパティに依存性注入を使用するにはどうすればよいですか?

分類Dev

パンダデータフレームで組み合わせの組み合わせを取得するにはどうすればよいですか?

分類Dev

疎結合/依存性注入とリッチドメインモデル間の競合を解決するにはどうすればよいですか?

分類Dev

Unicodeシンボルを組み合わせてカスタムxkbレイアウトを作成するにはどうすればよいですか?

分類Dev

MassTransitテストハーネスを使用して、コンストラクターの依存性注入でコンシューマーをテストするにはどうすればよいですか?

分類Dev

「ifステートメント」をモナークの日付と組み合わせて使用するにはどうすればよいですか?

分類Dev

Nest.jsフレームワークの依存性注入コンテナのみを使用するにはどうすればよいですか?

分類Dev

アノテーションを使用してSpringでコンストラクターベースの依存性注入を実行するにはどうすればよいですか?

分類Dev

DataFrame(パンダ)のインデックスとして組み合わせまたは文字列を使用するにはどうすればよいですか?

分類Dev

PLPGSQLでWITHをFORループと組み合わせて使用するにはどうすればよいですか?

分類Dev

.NET Coreの依存性注入を使用して、コンストラクターにオブジェクトを必要とするオブジェクトを解決するにはどうすればよいですか?

分類Dev

テンプレートと組み合わせてバイナリ算術演算子を使用するにはどうすればよいですか?

分類Dev

ゾーン化されていない日付とタイムゾーンを「組み合わせる」にはどうすればよいですか?

分類Dev

パンダ:リサンプリングとグループ化を組み合わせます。時間ビンに合計する前に、同じグループ内の値を平均するにはどうすればよいですか?

分類Dev

非型テンプレートパラメーターと型テンプレートパラメーターを組み合わせて関数をテンプレート化するにはどうすればよいですか?

分類Dev

ジェネリックインターフェイスに依存性注入を使用するにはどうすればよいですか?

Related 関連記事

  1. 1

    Azure Functionsでカスタムパラメーターバインディングと依存性注入を組み合わせるにはどうすればよいですか?

  2. 2

    パターンとグラデーションを1つのパスに組み合わせるにはどうすればよいですか?

  3. 3

    モジュール自体がコンストラクターとしてパラメーターを受け取る場合、依存性を注入するにはどうすればよいですか?

  4. 4

    matplotlibボタンをアニメーション機能と組み合わせて使用するにはどうすればよいですか?

  5. 5

    LUAでパターンマッチングを行うときに、単語と数字を組み合わせるにはどうすればよいですか?

  6. 6

    Pythonでbase32をhotp(ワンタイムパスワード)と組み合わせて使用するにはどうすればよいですか?

  7. 7

    ファサードパターンで依存性注入を使用するにはどうすればよいですか?

  8. 8

    ポアソン回帰でグループを組み合わせてコントラストを推定するにはどうすればよいですか?

  9. 9

    段落内でツールチップタグと段落マージンタグを組み合わせるにはどうすればよいですか?

  10. 10

    調査データを操作しているときに、パンダの列を組み合わせるにはどうすればよいですか?

  11. 11

    CPUとGPUグラフィックを組み合わせてパフォーマンスを向上させるにはどうすればよいですか?

  12. 12

    カルカースカレンダーと組み合わせてnotify-sendコマンドを使用するにはどうすればよいですか?

  13. 13

    継承と組み合わせてオブザーバーパターンを実現するにはどうすればよいですか?

  14. 14

    プロパティのタイプとインスタンスがサードパーティパッケージの一部である場合、プラグインのプロパティに依存性注入を使用するにはどうすればよいですか?

  15. 15

    パンダデータフレームで組み合わせの組み合わせを取得するにはどうすればよいですか?

  16. 16

    疎結合/依存性注入とリッチドメインモデル間の競合を解決するにはどうすればよいですか?

  17. 17

    Unicodeシンボルを組み合わせてカスタムxkbレイアウトを作成するにはどうすればよいですか?

  18. 18

    MassTransitテストハーネスを使用して、コンストラクターの依存性注入でコンシューマーをテストするにはどうすればよいですか?

  19. 19

    「ifステートメント」をモナークの日付と組み合わせて使用するにはどうすればよいですか?

  20. 20

    Nest.jsフレームワークの依存性注入コンテナのみを使用するにはどうすればよいですか?

  21. 21

    アノテーションを使用してSpringでコンストラクターベースの依存性注入を実行するにはどうすればよいですか?

  22. 22

    DataFrame(パンダ)のインデックスとして組み合わせまたは文字列を使用するにはどうすればよいですか?

  23. 23

    PLPGSQLでWITHをFORループと組み合わせて使用するにはどうすればよいですか?

  24. 24

    .NET Coreの依存性注入を使用して、コンストラクターにオブジェクトを必要とするオブジェクトを解決するにはどうすればよいですか?

  25. 25

    テンプレートと組み合わせてバイナリ算術演算子を使用するにはどうすればよいですか?

  26. 26

    ゾーン化されていない日付とタイムゾーンを「組み合わせる」にはどうすればよいですか?

  27. 27

    パンダ:リサンプリングとグループ化を組み合わせます。時間ビンに合計する前に、同じグループ内の値を平均するにはどうすればよいですか?

  28. 28

    非型テンプレートパラメーターと型テンプレートパラメーターを組み合わせて関数をテンプレート化するにはどうすればよいですか?

  29. 29

    ジェネリックインターフェイスに依存性注入を使用するにはどうすればよいですか?

ホットタグ

アーカイブ