gpt4 book ai didi

c# - 我应该将应用程序范围的对象传递给需要它的对象,还是应该使用单例?

转载 作者:可可西里 更新时间:2023-11-01 06:22:06 25 4
gpt4 key购买 nike

在我的特定情况下,我通过嵌套的 View Controller 向下传递一个“facebook”对象(即 MonoTouch.FacebookConnect.Facebook 的一个实例),它正在向项目添加一些不错的代码。在 AppDelegate 中实例化后,对象总是只有一个实例,并且在应用程序中的大多数 View Controller 中都使用它。所有使用 facebook 对象的 View Controller 在开头都有这样的东西:

public class MyViewController : UIViewController
{
Facebook facebook;

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

...除了顶层 View Controller ,对象在其中被实例化。

还有一种情况是它“通过”一个嵌套的 View Controller ,只是为了让它到达一个使用它的更深层嵌套的 View Controller 。

我知道单例通常不受欢迎并且违反 OOP 原则。我希望代码易于维护。我采用的方法是否正确,或者单例是否可以在不影响代码质量的情况下解决问题?

最佳答案

我会不惜一切代价避免使用 Singleton。您的方法鼓励松散耦合,并允许您通过模拟对象来提高可测试性(如果您从具体实现中转换它)。它通常会添加更多代码,但您的应用程序应该具有更好的可测试性。这允许您使用 IoC 容器并利用依赖注入(inject)。网络上和此处的 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();
}
}

围绕上述内容编写测试要容易得多。您还可以模拟每个接口(interface)的响应以创建各种测试。

public void SocialMediaWidgetTest()
{ //pseudo code
var testService = new MockObject(ConcreteSocialMediaWidgetService(MockObject_of_ISocialMediaWidget));
Assert.Equals(someImplementation_of_ISocialMediaWidgetResponse, testService.Foo());
}

关于c# - 我应该将应用程序范围的对象传递给需要它的对象,还是应该使用单例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15578710/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com