存储库工厂的存储库模式

时间:2015-06-14 17:42:23

标签: java android repository persistence repository-pattern

我试图改进我的Android持久层,以便在多个应用程序中使用。

到目前为止,我所做的是设置基本存储库抽象类和基本存储库接口,可在此处查看完整代码:https://github.com/grmaciel/android-repository-ormlite

接口:

public interface IRepository<T, Id> {
    public void save(T entity) throws SQLException;
    public void saveBatch(List<T> entities) throws Exception;
    public List<T> queryAll() throws SQLException;
    public T findById(Id id) throws SQLException;
    public void delete(T entity) throws SQLException;
}

现在我的所有存储库都扩展了我的基础存储库,如下所示:

public class DependencyRepository extends BaseRepository<Dependency> 
                                  implements IDependenceyRepository {
    public DependencyRepository(Context context) {
        super(context);
    }
}

我现在想要实现的是创建一个存储库工厂,允许人们不必使用new Instance()

在所有地方实例化他们的存储库

我所做的是创建一个必须使用具有类关系的容器初始化的Singleton工厂,如下所示:

public abstract class BaseRepositoryContainer {
    private final Context context;

    public BaseRepositoryContainer(Context context) {
        this.context = context;
    }

    public abstract <T extends IRepository> Map<Class<T>, Class<T>> getRepositoriesMap();

    public Context getContext() {
        return context;
    }
}

工厂:

public class RepositoryFactory {
    private Map<Object, Object> repositories = new HashMap<>();
    private final String LOG_TAG = RepositoryFactory.class.getSimpleName();
    private Context context;
    private static RepositoryFactory instance;
    private BaseRepositoryContainer container;

    private RepositoryFactory() {}

    public void init(BaseRepositoryContainer container) {
        this.container = container;
        this.context = container.getContext();
        this.configureRepositories(container.getRepositoriesMap());
    }

    private <T extends IRepository> void configureRepositories(Map<Class<T>, Class<T>> repositoriesMap) {
        for (Entry<Class<T>, Class<T>> entry : repositoriesMap.entrySet()) {
            this.registerRepository(entry.getKey(), entry.getValue());
        }

    }

    private <T extends IRepository> void registerRepository(Class<T> repInterface, Class<T> realRepository) {
        repositories.put(repInterface, this.createRepository(realRepository));
    }

    public <T extends IRepository> T getRepository(Class<T> repInterface) {
        if (container == null) {
            throw new UnsupportedOperationException("You should call init method providing a container.");
        }

        return (T) repositories.get(repInterface);
    }

    private <T extends IRepository> T createRepository(Class<T> repoClass) {
        try {
            T instance = repoClass.getConstructor(Context.class).newInstance(context);
            Log.d(LOG_TAG, "Repository " + repoClass.getSimpleName() + " created");
            return instance;
        } catch (InstantiationException e) {
            Log.d(LOG_TAG, e.toString());
        } catch (IllegalAccessException e) {
            Log.d(LOG_TAG, e.toString());
        } catch (InvocationTargetException e) {
            Log.d(LOG_TAG, e.toString());
        } catch (NoSuchMethodException e) {
            Log.d(LOG_TAG, e.toString());
        }

        return null;
    }

    public static RepositoryFactory getInstance() {
        if (instance == null) {
            instance = new RepositoryFactory();
        }

        return instance;
    }
}

然后就可以这样调用:

// when the application is first run
RepositoryFactory.getInstance().init(new RepositoryContainer(this));
// retreaving the repository
IDependenceyRepository repository = RepositoryFactory.getInstance()
                .getRepository(IDependenceyRepository.class);

所以我想知道这是否是一个很好的方法来帮助实现抽象?我不喜欢在没有义务人员的情况下调用工厂的init方法,唯一知道的方法就是如果你不打电话会抛出一个我不喜欢的例外。

有人能指出正确的方向吗?一种改进这种设计的方法?我不想稍后在我的项目中发现我已经创建了很多强大的依赖项并且很难改变某些东西。

任何建议都将不胜感激。

1 个答案:

答案 0 :(得分:4)

我改进代码所做的不是重新发明轮子,而是开始使用依赖注入库(Dagger 2 - http://google.github.io/dagger/)。

您可以根据需要定义在应用程序或活动中返回您所需的存储库的模块。