用于访问来自不同来源的相同数据的设计模式

时间:2015-12-15 09:02:00

标签: java android oop design-patterns

我有这个问题: 我有数据可以在云端保存本地和远程,以便能够从每个设备获取它们。现在,如果有连接,我必须从远程加载它们(如果有没有连接的更新,最终更新它们)并在本地保存任何更改,如果没有连接,我可以并且只能使用本地源。我首先想到了一个策略,但它显然是错误的,比我想到的代理,但我不知道它是否合适。 在我的设计过程中,我创建了一个managerPreferitiDB,它可以根据情况(可能带有State模式)访问localPreferitiDB(用于本地访问)和/或cloudPreferitiDB(用于远程访问)。我认为我应该有一个preferitiRetriever接口,由他们两个实现,然后在我的managerPreferitiDB代理中有两个或更多preferitiRetriever。

有什么建议吗?是否有更适合这种情况的模式?我正在使用Java for Android,谢谢

4 个答案:

答案 0 :(得分:2)

没有针对您的场景的GoF(Gang of Four)模式。当您面临涉及本地缓存和远程存储的更复杂问题时,GoF模式更低级别。 GoF模式不涉及网络。

也许您可以在Fowler的Catalog of Patterns of Enterprise Application Architecture中找到有用的内容,例如 Remote Facade 数据传输对象,但这些只是其中的一部分可能解决方案

我认为这是子系统设计的问题,因此您需要定义合适的抽象,然后在适当的地方使用GoF或其他模式来实现细节。

您将定义用于表示缓存/远程存储子系统的抽象不必响应特定的单个模式;正如我所知,这样一个系统没有公开的蓝图。

答案 1 :(得分:2)

在我看来,你的api设计必须解决两个问题。

首先,应该从客户端抽象存储库实现。通过这样做,它允许您更改Repository实现,而不会影响现有代码,即Repository的客户端。

其次,我们应该有两个单独的实现,即CloudRepository和LocalRepository。因为它们具有非常具体的职责,所以负责处理与云相关的持久存储,而另一个处理与设备相关的持久存储。我不是移动开发人员所以我认为这两个实现可能很复杂,并且可能会发生交换本地或云持久性技术

这是设计解决方案。它以某种方式混合了策略,代理模式。

第一个很简单。只要您通过构造函数或设置器将Repository的具体实现注入其客户端,那么客户端就不会耦合到任何存储库。在这种情况下,我强烈建议构造函数注入,因为客户端可能无法在没有存储库的情况下运行。

public class Client {
    private final Repository repository;
    public Client(Repository repository) {
       this.repository repository;
    }
}

对于第二个问题,我们只需要一个Repository实现,我称之为SwitchRepository。基本上,它协调云,本地存储库以实现数据访问的目标,这取决于Internet连接状态。

public SwitchRepository implements Repository {
     private Repository cloudRepository;
     private Repository localRepoistiry;

     public SwitchRepository(Repository cloudRepository, Repository localRepository) {
        this.cloudRepository = cloudRepository;
        this.localRepository = localRepository;
    }
    public void save(Data data) {
        // do whatever we want here
        if(isInternetConnected()) {

        } else {

        }
    }

  // the same for any operations of the Repository interface
}

总结一下:

public static void main(String[] args) {
    Repository localRepository = new LocalRepository();
    Repository cloudRepository = new CloudRepository();
    Repository switchRepository = new SwitchRepostitory(cloudRepository, localRepository);
    Client client = new Client(switchRepository);
}

答案 2 :(得分:0)

没有直接模式可以解决这个问题,但是有一些模式可以指出你正确的方向。使用的数据量和特异性将决定您需要的确切模式集合。从您所说的内容来看,这听起来像是使用State管理本地实例,而需要更新是一个好主意,并且将代理作为中介是正确的。 This paper from Vanderbilt University专门解决了这个问题,因为它与移动应用程序开发有关,应该对您有所了解。

答案 3 :(得分:0)

显然Proxy

这就是我使用代理实现它的方法 -

  1. 对数据加载器进行抽象
  2. 有一个实现从远程服务器加载它。
  3. 有另一个从本地数据源加载它的实现。
  4. 现在这就是诀窍 - 有第三个实现,它是一个封装其他实现的代理,检查连接状态并将其委托给正确的实现。
  5. 显然,调用对象不应该意识到它只使用代理提取。