当前,我的应用程序体系结构如下所示:

视图→演示者→一些异步执行器→DAOFactory→DAO(接口)→DAO(Impl)

目前,这种架构有效。主要是因为目前我只需要一种DAO。但是随着需求的增长,我需要扩展到多个DAO,每个DAO都有关于如何获取数据的自己的实现。

这是我的情况的说明:

主要的麻烦来自FooCloudDao,该代码从API加载数据。该API需要某种身份验证方法-登录期间存储的字符串 token (例如Session对象-是的,它也有自己的DAO)。

试图通过Session传递一个FooDaoFactory实例是很诱人的,以防万一没有连接,但似乎有点hacker和违反直觉。我可以想象的下一件事是从SessionDAOFactory中访问FooDaoFactory以获得Session的实例(然后在需要FooCloudDAO实例时将其传递)。

但是正如我所说,我不确定我是否可以做这样的事情-也许可以,但是这真的是正确的方法吗?

最佳答案

我认为您的问题实际上是FooCloudDao与其他组件具有不同的“依赖关系”,并且您要避免在途中将依赖关系传递给每个类。

尽管有很多设计模式可以解决您的问题,但我建议您看一下依赖注入/控制反转原理和框架。您将执行以下操作:


  • 您将为您的FooCloudDao所需的内容创建一个接口,例如:

  • interface ApiTokenProvider {
         string GetToken();
     }
    


  • 您将创建该接口的实现,并从会话中或任何来自何处的接口获取:

  • class SessionBasedApiTokenPrivider implements ApiTokenProvider {
        public string GetToken() {
            // get it from the session here
        }
    }
    


  • 上面定义的类需要在您选择的IoC容器中注册为,作为ApiTokenProvider的实现
    界面(这样,要求ApiTokenProvider的任何人都将被解耦
    从实际的实现->容器会给他
    正确实施)。
  • 您将在FooCloudDao 类上进行名为构造函数注入的操作(容器稍后将其用于“注入”
    您的依存关系):

  • public FooCloudDao(ApiTokenProvider tokenProvider) {
        // store the provider so that the class can use it later where needed
    }
    


  • 您的FooDaoFactory将使用 IoC容器及其所有依赖项来解析FooCloudDao (因此您不会
    FooCloudDao实例化new)



  • 执行以下步骤时,请确保:
  • FooDaoFactory仍然不通过
  • 传递依赖关系
  • 使您的代码更具可测试性,因为您可以在没有实际会话的情况下测试FooCloudDao(只能提供假接口实现)
  • 和控制反转带来的所有其他好处...

  • 关于会话的注意事项:如果遇到在SessionBasedApiTokenProvider中获取会话的问题,大多数情况下,会话本身也已向IoC控制器注册,并在需要时注入。

    07-24 09:51