How do I design a DataSource/Service class to get network or local data?

suppose a very common scenario:
XYZMovie (a fictional movie website) provides an interface that allows developers to get basic information about a movie (movie name, actors, screening time, ratings, etc.)

The
interface looks like this: http:api.xyzmovie.com/get?nam...

I used the crawler to cache the data of the site to the local database. Now there is a movie query program, which should be able to set local or network priority queries. If the local or network queries fail, change to another query:

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

is there a better design pattern?


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

use CountDownLatch, set to 1, and multithread to get the remote local. Whoever gets it first returns.
if you run successfully several times, you will find that you can have different values
because
Thread.sleep (new Random (). NextInt (3) * 1000); randomly set their speed

just as if you don't have it in your local database, you will naturally wait for the remote, so you don't have to call
countDownLatch.countDown () locally;
the main thread will wait

all the time.

does not find it necessary to use design patterns. If I have to, I think we can distinguish between two ways through the path of url, one is called cache (that is, your local), and the other is called origin (that is, your network).

MySQL Query : SELECT * FROM `codeshelper`.`v9_news` WHERE status=99 AND catid='6' ORDER BY rand() LIMIT 5
MySQL Error : Disk full (/tmp/#sql-temptable-64f5-1e7b14d-4dcf9.MAI); waiting for someone to free some space... (errno: 28 "No space left on device")
MySQL Errno : 1021
Message : Disk full (/tmp/#sql-temptable-64f5-1e7b14d-4dcf9.MAI); waiting for someone to free some space... (errno: 28 "No space left on device")
Need Help?