DAOFactory和服务模式

时间:2013-11-19 16:42:59

标签: java design-patterns web dao

我只想扩展本教程Abstract DAO

我想介绍UserService(接口),JdbcUserService(Class)以及类似的服务及其实现。

1)现在我应该在一个地方放置一个DAOFactory实例并在所有这些服务中使用它,还是应该在每个服务中实例化DAOFactory。如何为每种方法编写服务测试。

2)如何删除像DAOFactory.getInstance("javabase.jdbc");这样的硬编码,并在整个应用程序中执行此设置。

3)此外,从Web应用程序的角度来看(多线程)可能会做出哪些更改。

2 个答案:

答案 0 :(得分:0)

  1. 您应该使用通用工厂来创建所有数据库访问类,因为它们将是相关类的“系列”。为工厂创建一个接口,然后使用DAO实现类的实现。通过这种方式,您可以将系统更改为使用其他方式存储数据,或者将其模拟为测试。
  2. 使用工厂类隐藏此实现细节。此外,如果可能的话,您不应该公开原始DAO对象。最好为“人”和“工作函数”之类的东西创建一个有限的接口,它只暴露你需要的方法,甚至可能在DAO方法的更高层次上。同样,这允许您稍后隐藏详细信息并更改存储的实现(或用于测试/模拟)
  3. 将同步添加到工厂生成的类中。您需要决定amodel,但最简单的方法是首先同步所有方法,然后在需要更高性能时放松锁定。
  4. 另外:您可能希望使用“Singleton”模式来确保只创建DAOFactory类的一个实例。

    这样的事情......

    请注意,我的“Singleton”不执行单例原则。它只是用作目前使用的工厂的常用方式。

    interface Person {
      String getName();
      void setName();
    }
    
    interface PersonStorage {
      Collection<Person> getPersonsByName(final String name);
    }
    
    class DAOPerson implements Person {
    
      public synchronized String getName() {
        // Implementation here 
      }
    
      public synchronized void setName() {
        // Implementation here
      }
    
    }
    
    interface Factory {
      PersonFactory getPersonFactory();
    }
    
    class DAOPersonFactory implements PersonFactory {
      // Implementation
    }
    
    class DAOFactory implements Factory {
    
      PersonFactory getPersonFactory() {
        DAOPersonFactory res = new DAOPersonFactory();
        // Set up the instance, probably connect it to the underlying DAO
        return res;   
      }
    }
    
    class FactorySingleton {
      private Factory fac;
    
      FactorySingleton(final Factory implementation) {
        this.fac = implementation;
      }
    
      Factory getFactory() {
        return fac;
      }    
    
    }
    

答案 1 :(得分:0)

让你的类解析(内部,而不是通过构造函数或setter)它们的依赖关系通常是一个测试能力反模式。例如,如果您对A类具有复杂的依赖关系,并且您希望将其模拟以用于测试目的,因为依赖关系本身由类解析,您将无法使用模拟(除非您正在修改A类逻辑,它本身就是另一种糟糕的测试实践)。测试能力问题当然是导致开发人员普遍依赖注入流行的因素之一。

如果使用依赖注入容器(例如Spring或jboss-weld ...),您的工厂将是由容器管理的bean。您可以将其范围定义为Singleton,这与您在Service层类中共享同一实例的需要相对应。

测试时,您可以轻松调整依赖项容器,为您提供模拟实例,以简化测试。