2010-08-30 54 views
2

我想知道,我最近读了一篇文章,谈到使用单例模式的缺点,说全球变量发生的缺点,正确地说,单例违反了我们从OOP学校学到的许多规则,单责任原则,接口和抽象类的编程,而不是具体的类......所有这些好东西。我想知道你如何像数据库连接类一样工作,你只需要一个连接到你的数据库和你的数据库的一个对象漂浮。作者提到了依赖注入原则,我认为它依赖于依赖倒置规则。我如何知道和控制什么对象作为依赖被传递,而不是我创建这个类的事实,并期望每个人都使用它,并确保它们使用正确的资源?!面向对象编程原理

+0

IOC + DI:http://martinfowler.com/articles/injection.html – 2010-08-31 00:50:06

回答

3

编辑:这个答案假定你使用的是依赖注入容器,你自己写的一个,或者你从库中获得的。如果没有,那么使用DI容器:)

我怎么知道和控制什么对象被传来传去的比我创建的类并用它玩好,并确保每个人都期待的事实以外的依赖,他们正在使用正确的资源?

合同

的口头合同 - 你写了一个设计规范,说:“你不可直接实例化这个类”和“不可绕过你的依赖注入容器有任何对象如果你必须通过容器“。

编译器契约 - 你给它们一个依赖注入容器,并且它们通过抽象接口抓取它的实例。如果只希望使用单个实例,则可以为它们提供一个命名实例,它们会同时提取名称和接口。

ISomething instance = serviceLocator.ResolveInstance<ISomething>(
    "TheInstanceImSupposedToUse"); 

您也可以让你的所有的具体类民营/内部/什么具备的,你,只为他们提供一个抽象的接口来对运行。这将阻止他们自己实例化类。

// This can only be instantiated by you, but can be used by them via ISomething 
private class ConcreteSomething : ISomething 
{ 
    // ... 
} 

通过代码审查

你让整个集团的编码和设计标准的公平性,并确保它们是由组内的每个人都知道。

您使用的是源代码控制机制,并且在他们签入之前需要进行代码审查。您可以阅读代码,了解它们链接的内容,包含哪些标头,实例化哪些对象以及传递哪些实例。

如果他们在代码审查过程中违反了您的规则,那么在修复代码之前不要让他们签入。可选地,对于屡犯者,你让他们付给你一美元,你让他们买午餐,或者你雇用一个不同的承包商来替换他们。无论在你的组内工作得好:)

2

对于那些谁批评Singleton模式的基础上,SRP,这里是一个opposing view。另外,我发现依赖注入容器可以创建尽可能多的问题。也就是说,我正在使用一个很有前途的折中方案,如another post所述。

1

不要把你在任何地方看到的东西当作绝对真理。阅读它,理解它,然后然后你可以看到什么时候最好应用某些东西。在你的情况下,你为什么不想创建一个静态单例?

+0

因为可能会有更好的抽象。通常,更灵活的方法会使代码更容易重构或重用。例如,有些原因希望能够并行运行多个版本的代码,即使通常只想保留一个连接,也可以单独连接到数据库。简单的单例不会让您灵活地更改设计以支持该场景。 – 2010-08-31 00:42:00

+0

Merlyn我同意你的意见。我正在考虑做一些事情,你刚刚说的话引发了我的想法。很高兴! – 2010-09-01 14:14:05