服务式架构的设计模式

6

在以下简化组件存在的情况下,哪种设计模式比较智能:

3个组件:
- GUI
- 数据获取器
- 数据库

Design

我无法访问互联网上的服务器,它只是一个数据源。互联网上的数据始终是更新的,本地数据库只是互联网上数据库的副本(缓存)。GUI 可以请求和更新本地缓存,类似服务的组件异步获取最新数据,这可能需要一些时间。 GUI 仅显示可以同步获取的本地数据库中的数据。

因此,我的问题是,您会使用哪些类来实现具有进度条功能的长期运行的服务?是否有更好的设计方法来解决这种“问题”?是否有更好的做法?

1个回答

1

关于服务组件:

  • 一个接口(方法)来启动更新过程。通常,此服务将返回一个jobId以指示正在后台处理的作业。
  • 另一个接口(方法)根据特定的jobId获取状态。此服务的实现可以返回状态、完成百分比或任何其他相关信息,以告诉调用者更新过程的当前状态。此方法的实现需要能够报告增量进度(例如报告本地存储中的增量存储),以便制作准确的进度条;否则,UI最好只显示旋转的进度条。
    • 请注意,如果无法实现这种增量报告,则更新过程可能应该使用典型的AsyncTask用法,在后台执行更新并在完成时向用户报告。如果此操作可能需要一段时间,则可以通过Android通知栏或推送通知实现更新的完成。
假设您有获取更新进度的接口,您可以利用AsyncTask onProgressUpdate来报告更新的进度。该方法专门为此设计。
您的步骤大致如下:
  • 通过一个AsyncTask执行更新接口。由于您的更新是异步进行的,因此此特定任务应该很快返回,其中包含状态报告,指示执行是否成功运行或因某些异常而失败,以及它当前正在执行的jobId
  • 启动另一个AsyncTask,该任务正在检查更新的状态并通过onProgressUpdate报告进度。 AsyncTask大致如下:

public class GetUpdateStatusAsyncTask extends AsyncTask {
    protected Integer doInBackground(Integer... param) {
        // this is the jobId that you get from the previous AsyncTask that you use to kick off the 
        // the update process
        int jobId = param[0];
        double percentCompleted  = fetchStatus(jobId);

        while(percentCompleted != 100.00) {
            publishProgress(percentCompleted);
        }

        // return status code
        return 1;
    }

    protected void onProgressUpdate(Double... progress) {
        // set the progressBar here
    }

    protected void onPostExecute(Long result) {
       // done, handle status code
    }

    private double fetchStatus(int jobId) {
        double percentCompleted = 0.0;
        // call interface to get the update based on the jobId
        // return percentCompleted status or make a more complex object if you need 
        // more detail info
        return percentCompleted;
    }
}

也许我应该更明确地解释我的第一篇帖子。我无法访问互联网上的服务器,它只是一个最新的数据源。我获取数据并更新本地数据库。 - kadir
如果Service Like组件是一个本地类,为了准确报告进度,仍然需要接口能够在该类内获取当前进度。如果没有该接口的可用性,你所能做的最好就是显示旋转进度条并等待更新完成。我会更新答案。 - momo
看起来不错,但是为什么要启动另一个异步任务来轮询第一个的进度呢? - kadir
如果你想要像你描述的那样从互联网异步获取数据并获得进度,你需要运行两个线程(一个用于通过互联网获取更新,另一个用于轮询进度)。否则,获取数据的线程将阻塞进度轮询。如果可以进行增量进度报告,那么应该从ServiceLikeComponent内部启动描述的第一个AsyncTask,并且它不需要被声明为AsyncTask(或者你可以将其编码为在一个线程中运行的Runnable)。 - momo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接