javaNoober
javaNoober

Reputation: 1338

Design Pattern that define action and target

I have a GenericDAO which delegates its operations to a DataSource class

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

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

The issue I'm having right now is that we want it to work with multiple DataSources. This leaves me with 2 alternatives

1) make a setter in DAO for datasource and use it before every operation

2) create each child of BaseDAO n times per number of datasources

I would like DataSource to get out of DAO, but then how the actions can get delegated to it?

Upvotes: 1

Views: 271

Answers (4)

Anand
Anand

Reputation: 14915

Well I think, you should try and use dependency injection in this case. Your base class would be abstracted from type of datasource. So even if you are adding a new type of datasource the only change that you would end up doing would be the factory method which would generate a type of DataSource object based upon current request and hence increase loose coupling of your application

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;

Upvotes: 0

axtavt
axtavt

Reputation: 242686

I guess you want to implement something like multitenancy: when request comes from the user A, all DAO involved into processing that request should talk to user A's DataSource, and so on.

If so, DataSource is a part of context for your request, and one possible option to store this kind of contextual data is to use ThreadLocal:

  • When request comes, you put the appropriate DataSource into ThreadLocal
  • All DAOs obtain the DataSource from that ThreadLocal.
    Obviously, for the sake of Single Responsibility Principle it would be better to hide this logic behind a factory and inject that factory into your DAOs, so that DAOs will call factory.getCurrentDataSource() for each operation.
  • Clear ThreadLocal when you finished processing of the request.

Note that it only works if each request is processed by a single thread.

Upvotes: 1

JamesB
JamesB

Reputation: 7894

I wouldn't use a setter for the data source, I would pass it in the constructor for the DAO. Doesn't seem right to be able to change the data source during the life of the DAO object.

Upvotes: 0

mprabhat
mprabhat

Reputation: 20323

You can use a factory for creating your datasource, so depending on your requirement create your datasource and then if you can use dependency injection to have your datasource injected to your DAO.

To get rid of datasource in DAO you can use Delegate Pattern, inject delegator in your DAO, your delegate will have reference of DataSource.

Also to note if you persist with just one generic DAO, your DAO may eventually get blotted with methods which are not generic but more specific to a certain functionality of your application, IMHO you should also consider breaking your DAO to more specific level leaving the generic DAO actually do the generic work.

Upvotes: 1

Related Questions