3

私の特定の状況では、ネストされたビュー コントローラーを介して "facebook" オブジェクト (つまり、MonoTouch.FacebookConnect.Facebook のインスタンス) を渡し、適切なコードをプロジェクトに追加しています。AppDelegate でインスタンス化された後、オブジェクトのインスタンスは常に 1 つだけ存在し、アプリのほとんどのビュー コントローラーで使用されます。facebook オブジェクトを使用するすべてのビュー コントローラーには、最初に次のようなものがあります。

public class MyViewController : UIViewController
{
    Facebook facebook;

    public MyViewController (Facebook facebook)
    {
        this.facebook = facebook;
    }
    // ...
}

...オブジェクトがインスタンス化される最上位のView Controllerを除きます。

それを利用するより深くネストされたView Controllerに取得するためだけに、ネストされたView Controllerを「通過」するシナリオもあります。

シングルトンは一般的に嫌われており、OOP の原則に反していることを私は知っています。コードを簡単に保守できるようにしたい。私は正しいアプローチを取っていますか、それともシングルトンはコードの品質を損なうことなくトリックを行いますか?

4

4 に答える 4

6

私はシングルトンを絶対に避けます。あなたのアプローチは疎結合を促進し、オブジェクトをモックアウトすることでテスト容易性を高めることができます (具体的な実装から変換した場合)。通常、コードが追加されますが、アプリケーションのテスト容易性が向上するはずです。これにより、IoC コンテナーを使用し、依存性注入を利用できます。Web や StackOverflow には、このようなトピックに関するすばらしい記事や投稿がたくさんあります。

おそらく、シングルトンは次のようになります。

public class MyViewController : UIViewController
{
    public MyViewController ()
    {
    }

    public void Foo()
    {
        FaceBookSingleton.Instance.DoSomeAction();
        FaceBookSingleton.Instance.Something = 4;
    }
}

どのようにテストを行いますFoo()か? 重大な変更を導入した場合、どうすればすぐにわかりますか? 依存関係グラフがどのように見えるかをどのように知ることができますか? このようなコードをテストするのはより困難です。コードベースをブラウジングして何かを壊したかどうかを調べようとする人を当てにしないでください。テスト可能なコードを書くことで、彼らとあなた自身を助けてください。

今、おそらくそのようなものを見てください:

public interface ISocialMediaWidget
{
    ISocialMediaWidgetResponse DoSomeUnitOfWork();
}


public class ConcreteSocialMediaWidgetService
{
    protected readonly ISocialMediaWidget socialMediaWidget;

    public ConcreteSocialMediaWidgetService(ISocialMediaWidget widget)
    {
        this.socialMediaWidget = widget;
    }

    public ISocialMediaWidgetResponse Foo()
    {
        return socialMediaWidget.DoUnitOfWork();
    }
}

前述のテストを書くのはずっと簡単です。各インターフェイスからの応答をモックアウトして、あらゆる種類のテストを作成することもできます。

public void SocialMediaWidgetTest()
{   //pseudo code
    var testService = new MockObject(ConcreteSocialMediaWidgetService(MockObject_of_ISocialMediaWidget));
    Assert.Equals(someImplementation_of_ISocialMediaWidgetResponse, testService.Foo());
}
于 2013-03-22T20:01:30.063 に答える
2

まず、シングルトンは、「ファクトリ」やメモ化など、他の完全に受け入れられる OO 戦略の代替構文にすぎません。

これは構文の問題であり、組織内で各構文が意味するものです。これを行う場合、製品に対して何らかの作業が行われる可能性があることが組織内で暗示されていますMyClass.Currentか?

public class MyClass
{
  public static MyClass Current
  {
    get
    {
      if (SomeSortOfCache['MyClass.Current'] == null) {
        // do something to get populate it.
      }
      return SomeSortOfCache['MyClass.Current'];
    }
  }
}

または、あなたの組織は次のようなものを好むでしょうか:

public class MyClass
{
  public static MyClass GetCurrent()
  {
    if (SomeSortOfCache['MyClass.Current'] == null) {
      // do something to get populate it.
    }
    return SomeSortOfCache['MyClass.Current'];
  }
}

または、ファクトリと考えたい場合は、メソッドBuildMyClass()またはを呼び出しますCreateMyClass()。内部のメカニズムはほとんど同じです。これは主に、組織が各構文と命名規則について行う仮定の問題です。

次に、 のインスタンスを 1 つだけ存在させたい、または許可する必要があることを確認しました。したがって、コードの量を最小限に抑えて、これを適切に促進するパターンを使用することをお勧めします。

于 2013-03-22T19:57:15.453 に答える
2

この場合、多くの反復コードを排除し、アプリケーションを迅速に構築する際の変更に対する柔軟性を高めるため、シングルトンの方が優れたソリューションのように思われます。

シングルトンは、Facebook オブジェクトの仲介者としても機能し、アプリケーションのさまざまな部分を簡単に使用できるようにします。

本質的に制限されているリソースは、シングルトンを介してアクセスするのに適しています。

于 2013-03-22T20:01:57.863 に答える
0

必要なインスタンスは常に 1 つだけなので、シングルトン アプローチを使用することをお勧めします。

于 2013-03-22T19:59:42.800 に答える