Java 从不同来源访问相同数据的设计模式

Java 从不同来源访问相同数据的设计模式,java,android,oop,design-patterns,Java,Android,Oop,Design Patterns,我有一个问题: 为了能够从每台设备上获取数据,我可以在云上保存本地和远程数据。现在,如果有连接,我必须从远程加载它们(如果有没有连接的更新,最终更新它们),并将任何更改也保存在本地,如果没有连接,我可以也必须只使用本地源。我首先想到了一个策略,但它显然是错误的,比我想到的代理,但我不知道它是否适合。 在我的设计过程中,我创建了一个managerPrefertiDB,在这种情况下(可能使用状态模式)可以访问localPreferitiDB(用于本地访问)和/或cloudPreferitiDB(用于

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

有什么建议吗?有更好的模式适合这个吗?我正在使用Java for Android,谢谢

没有能够解决您的场景的GoF(四人帮)模式。当您面临涉及本地缓存和远程存储的更复杂问题时,GoF模式的级别更低。GoF模式不处理网络

也许您可以在ByFowler中找到一些有用的东西,例如远程外观和数据传输对象,但这些只是可能的解决方案的一部分

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


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

没有直接的模式可以解决这个问题,但只有少数模式为您指明了正确的方向。所用数据的数量和特殊性将决定您需要的确切模式集合。根据您所说的,在需要更新时使用State管理本地实例似乎是个好主意,而将代理作为中介是正确的。专门解决这个问题,因为它与moblie应用程序开发有关,应该对您有深刻的见解。

这就是我将如何使用代理实现它-

  • 对数据加载器进行抽象
  • 有一个从远程服务器加载它的实现
  • 有另一个从本地数据源加载它的实现
  • 现在这就是诀窍——有第三个实现,它是封装其他实现的代理,检查连接状态并将其委托给正确的实现

  • 显然,调用对象不应该知道它只是在抽象中使用代理。

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

    首先,存储库实现应该从其客户机中抽象出来。通过这样做,您可以在不影响现有代码(存储库的客户端)的情况下对存储库实现进行更改

    public class Client {
        private final Repository repository;
        public Client(Repository repository) {
           this.repository repository;
        }
    }
    
    其次,我们应该有两个独立的实现,即CloudRepository和LocalRepository。因为他们有非常具体的职责,一个负责与云相关的持久性存储,另一个负责与设备相关的持久性存储。我不是一名移动开发人员,所以我认为这两种实现可能很复杂,并且很可能会交换本地或云持久性技术

    这是设计方案。某种程度上,这是策略和代理模式的混合

    第一个很简单。只要通过构造函数或setter将存储库的具体实现注入it客户机,那么客户机就不会耦合到任何存储库。在这种情况下,我强烈建议使用构造函数注入,因为如果没有存储库,客户端可能无法正常工作

    public class Client {
        private final Repository repository;
        public Client(Repository repository) {
           this.repository repository;
        }
    }
    
    对于第二个问题,我们只需要另外一个存储库实现,我称之为SwitchRepository。基本上,它协调云、本地存储库来实现数据访问的目标,这取决于互联网连接状态

    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);
    }
    

    不需要实际的模式,只需将保存逻辑封装在
    managerPrefertiDB
    中,这样使用它的类就不需要知道保存是远程发生还是本地发生,并且管理器在保存时检查是否建立了连接,并相应地在本地或远程保存。