定义动作和目标的设计模式

时间:2012-05-22 06:28:42

标签: java design-patterns

我有一个GenericDAO,它将其操作委托给DataSource类

public class BaseDAOImpl<T> implements BaseDAO<T> {     
    DataSource ds;      

    public T update(T entity) {
    ds.update(entity);
    }

我现在遇到的问题是我们希望它可以与多个DataSource一起使用。这给我留下了两个选择

1)在DAO中为数据源创建一个setter并在每次操作之前使用它

2)每个数据源数量创建BaseDAO的每个子节点n次

我希望DataSource摆脱DAO,但接下来如何将操作委托给它?

4 个答案:

答案 0 :(得分:1)

您可以使用工厂创建数据源,因此根据您的要求创建数据源,然后使用依赖注入将数据源注入DAO。

要删除DAO中的数据源,可以使用委托模式,在DAO中注入委托者,您的委托将引用DataSource。

另外需要注意的是,如果你坚持使用一个通用的DAO,你的DAO最终可能会被一些不通用但更具体的应用程序的方法所污染,恕我直言你还应该考虑将你的DAO打破到更具体的水平离开通用DAO实际上是做通用工作。

答案 1 :(得分:1)

我想你想要实现多租户之类的东西:当请求来自用户A时,处理该请求所涉及的所有DAO都应该与用户A的DataSource对话,依此类推。

如果是这样,DataSource是您请求的上下文的一部分,存储此类上下文数据的一种可能选项是使用ThreadLocal

  • 当请求到来时,您将相应的DataSource放入ThreadLocal
  • 所有DAO都从DataSource获得ThreadLocal 显然,为了单一责任原则,最好将这个逻辑隐藏在工厂后面并将该工厂注入您的DAO中,以便DAO为每个操作调用factory.getCurrentDataSource()
  • 处理完请求后清除ThreadLocal

请注意,它仅在每个请求由单个线程处理时才有效。

答案 2 :(得分:0)

我不会使用setter作为数据源,我会在DAO的构造函数中传递它。在DAO对象的生命周期内能够更改数据源似乎不对。

答案 3 :(得分:0)

我认为,在这种情况下你应该尝试使用依赖注入。您的基类将从数据源类型中抽象出来。因此,即使您要添加新类型的数据源,您最终会做的唯一更改是工厂方法,该方法将根据当前请求生成一种DataSource对象,从而增加应用程序的松散耦合

interface IDataSource<T>
{
    T update<T>(T entity);
}

public ConcereteDataSource<T> : IDataSource<T>
{
    public T update<T>(T entity)
    {
        //Concerete implementation
    }
}


public class BaseDAOImpl<T> implements BaseDAO<T> 
{     

    public IDataSource ds {get;set;}
    public T update(T entity) {
    ds.update(entity);
}

//where you try to instansiate a new instance of Base DAO

//Factory to create a new instance of datasource for this context
IDataSource contextualDs = GetDataSourceForThisUser();

BaseDAOImpl<SomeType> dao = new BaseDAOImpl<SomeType>();
//inject the dependency
dao.ds = contextualDs;