2

我正在尝试摆脱代码库中的静态类、静态辅助方法和单例类。目前,它们几乎遍布整个代码,尤其是实用程序类和日志库。这主要是由于需要模拟能力以及面向对象的设计和开发问题,例如可扩展性。将来我可能还需要引入某种形式的依赖注入,并愿意为此敞开大门。

基本上,我遇到的问题是关于传递常用引用的方法。这些是代码库中几乎每个类都使用的对象,例如日志接口、实用程序(帮助程序)类接口,可能还有一个类的实例,该类的实例为大多数类相关的程序集保存内部公共状态。

据我所知,有两种选择。一种是定义一个存储公共引用的类(或接口),如果您愿意,还可以定义一个上下文,并将上下文传递给创建的每个对象。另一种选择是将几乎每个类的每个公共引用作为单独的参数传递,这将增加类构造函数的参数数量。

这些方法中哪一种更好,每种方法的优缺点是什么,是否有更好的方法来完成这项任务?

4

3 回答 3

1

我通常使用上下文对象方法,并将上下文对象传递给对象的构造函数或方法——取决于哪个最有意义。

上下文对象模式可以采用几种形式。

您可以定义一个具有您需要的成员的接口,或者您可以生成一种容器类。例如,在编写松散耦合的组件时,我倾向于让我实现的每个组件都有一个匹配的接口,以便在需要时可以重新实现它。然后我在“管理器”对象上注册对象,如下所示:

public interface IServiceManager
{
    public T GetService<T>();
    public T RequireService<T>();
    public void RegisterService<T>(T service);
    public void UnregisterService<T>(T service);
}

在幕后有一个从类型到对象的映射,这使我能够非常快速地将大量不同的组件组装成一个工作整体。每个组件都通过接口请求其他组件,而管理器对象将它们粘合在一起。(如果您正确地编写了组件,您甚至可以在进程运行时将一项服务换成另一项服务!)

可以按照以下方式注册服务:

class FooService : IFooService { }

// During process start-up:
serviceManager.RegisterService<IFooService>(new FooService());

由于字典查找,这种方法比平面接口方法有更多的开销,但它允许我构建非常复杂的系统,可以很容易地使用不同的服务实现重新部署。(而且,像往常一样,我遇到的任何瓶颈都不是从字典中查找服务对象,而是在其他地方,例如数据库。)

于 2013-04-22T21:03:52.747 回答
1

你会得到不同的意见,但通常为每个依赖项向构造函数传递一个单独的参数是首选的,原因如下:

  • 它清楚地定义了类的实际依赖关系——使用“上下文”,如果不深入研究代码,您不知道使用了上下文的哪些部分。
  • 通常,构造函数有很多参数是一种设计味道,因此使用构造函数注入可以帮助您发现设计缺陷。
  • 测试时,您可以模拟单个依赖项,而不必模拟整个上下文
于 2013-04-22T21:11:36.893 回答
0

我建议将作为参数传递给构造函数。这对于依赖注入和单元可测试性(模拟)都有很大的优势。

于 2013-04-22T21:02:20.737 回答