这是什么模式(“Provider”)?

4

在工作中,我们正在使用一种“设计模式”,我在GoF书中并没有找到它(但这可能是由于我在这方面缺乏能力,我只是浏览了一下模式),而且我仍然有些怀疑。

假设我们有一个多项目解决方案,其中包含一个名为DataAccess的项目,该项目管理数据访问。通常情况下,我看到它的结构如下:

Providers (Folder)
 - DataAccessProvider.cs

Interfaces (Folder)
 - IFileLoader.cs

Implementors (Folder)
 - FileLoader.cs

在这里,FileLoader 将是接口 IFileLoader 的一个 internal 实现,提供程序如下:

public static class DataAccessProvider
{
  public static IFileLoader FileLoader
  {
    get { return new FileLoader(); }
  }
}

这是什么类型的设计模式(如果有),除了遮盖特定的 IFileLoader 接口实现,它还有哪些真正的用途?
此外,这样写真的算是“好风格”吗?举个例子,如果有很多类似的调用会发生什么?
string content = DataAccessProvider.FileLoader.LoadContentFromFile("abc.txt");

每当需要调用 new FileLoader() 时,这样做会比较繁琐。有没有更优雅的方式实现类似的功能呢?


在我看来,它很像一个专门的服务定位器。而ServiceLocator是一种反模式。 - Firo
1个回答

8
在这个例子中,DataAccessProvider 是一个简单工厂方法(模式)的示例。通常情况下,你会有一个名为 GetFileLoader()CreateFileLoader() 的方法,而不是属性版本,但结果是相同的。
返回 IFileProvider 而不是 FileProvider 的目的是为了依赖反转,这样就可以编写其他类型的 FileProvider 并将它们注入到应用程序中,而不需要重新设计或重新编译所有依赖于 IFileProvider 的对象。这不是关于掩盖。
如果担心创建多少个 FileLoader 实例,则可以使用 Singleton 模式来处理该对象。然而,如果 FileLoader 是轻量级对象,那么通常不会成为问题,因为 CLR 垃圾收集器会自动处理它。

啊,谢谢!不过我在想这种模式是否总是有用,因为我们在解决方案中的几乎每个项目中都在使用它,而且有90%的时间只会(并且永远)有一个相应接口的实现。此时,提供程序类成为获取用于数据访问的不同接口实现的方法集合。如果您知道永远不会替换该实现,那么这仍然是一个好的实践吗? - InvisiblePanda
1
从技术角度来看,没有什么东西总是有用的。话虽如此,通常最佳实践是使用接口,因为它可以带给你很多好处(有助于依赖反转、单元测试、模拟、IoC容器等等)。如果您正在使用接口,那么使用IoC容器或工厂是最简单的方法。交换能力很有用,但并非必要,只要价值在那里即可。 - Silas Reinagel
如果这是一个非常小的或个人项目,那么遵循这些模式可能不值得花费时间和精力。 - Silas Reinagel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接