如何设计一个 DataSource/Service 类以获取网络或本地数据?

发布于 2022-09-11 17:17:43 字数 721 浏览 14 评论 0

假设一个很常见的场景:
XYZMovie(一个虚构电影网站)提供了接口可以让开发者获取某部电影的基本信息(电影名、演员、放映时间、评分等)

接口类似这样:http:api.xyzmovie.com/get?nam...

我利用爬虫缓存了该网站的数据到本地数据库,现在有一个电影查询程序,它应该能设置本地或网络优先查询,如本地或网络查询无果则换另一种查询:

class XYZMovieDataSource
{
    XYZMovie GetMovie(string id or name, etc, priority)
    {
        XYZMovie m;
        if(priority == local) { dosomething }
        else { dosomething }
        return m; 
    }
    
    XYZMovie GetMovieFromLocal(string id or name, etc) { dosomething }
    XYZMovie GetMovieFromNetwork(string id or name, etc) { dosomething }
}

请问有什么更好的设计模式吗?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

逐鹿 2022-09-18 17:17:43

没有发现有使用设计模式的必要,如果非要说,我觉得可以通过url的路径将两种方式区分开,一个叫cache(也就是你的local),一个叫origin(也就是你的network)。

故人爱我别走 2022-09-18 17:17:43
import java.util.Random;
import java.util.concurrent.CountDownLatch;

public class MovieDataSource {
    public static void main(String[] args) {
        Movie movie = new MovieDataSource().getMovie("码匠笔记");
        System.out.println("最终得到视频:" + movie);
    }

    public Movie getMovie(String id) {
        CountDownLatch countDownLatch = new CountDownLatch(1);
        MovieGetter remoteMovieGetter = new RemoteMovieGetter(id, countDownLatch);
        MovieGetter localMovieGetter = new LocalMovieGetter(id, countDownLatch);

        new Thread(remoteMovieGetter).start();
        new Thread(localMovieGetter).start();

        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            System.out.println("这都出异常了?还想获取啥");
        }

        if (remoteMovieGetter.getMovie() != null) {
            return remoteMovieGetter.getMovie();
        }
        if (localMovieGetter.getMovie() != null) {
            return localMovieGetter.getMovie();
        }

        return null;
    }

    public static abstract class MovieGetter implements Runnable {
        protected String id;
        protected CountDownLatch countDownLatch;

        public MovieGetter(String id, CountDownLatch countDownLatch) {
            this.id = id;
            this.countDownLatch = countDownLatch;
        }

        public abstract Movie getMovie();
    }

    public static class RemoteMovieGetter extends MovieGetter {
        public RemoteMovieGetter(String id, CountDownLatch countDownLatch) {
            super(id, countDownLatch);
        }

        private Movie movie;

        @Override
        public Movie getMovie() {
            return movie;
        }

        @Override
        public void run() {
            System.out.println("拉取远程视频");
            try {
                Thread.sleep(new Random().nextInt(3) * 1000);
                System.out.println("获取远程视频");
                movie = new Movie("获取远程视频");
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                countDownLatch.countDown();
            }
        }
    }

    public static class LocalMovieGetter extends MovieGetter {

        public LocalMovieGetter(String id, CountDownLatch countDownLatch) {
            super(id, countDownLatch);
        }

        private Movie movie;

        @Override
        public Movie getMovie() {
            return movie;
        }

        @Override
        public void run() {
            System.out.println("拉取本地视频");
            try {
                Thread.sleep(new Random().nextInt(3) * 1000);
                System.out.println("获取本地视频");
                movie = new Movie("获取本地视频");
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                countDownLatch.countDown();
            }
        }
    }

    public static class Movie {
        private String name;

        public Movie(String name) {
            this.name = name;
        }

        @Override
        public String toString() {
            return this.name;
        }
    }
}

使用 CountDownLatch ,设置为 1,同时多线程去获取远程的本地,谁先获取到,返回谁。
多次运行成功你会发现可以有不同的值
因为
Thread.sleep(new Random().nextInt(3) * 1000); 随机设置他们的快慢

正如如果你本地数据库中没有,那么自然就去等待远程了,那么你本地可以不调用
countDownLatch.countDown();
主线程就会一直等待

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文