Как добиться механизма кеширования с помощью шаблона проектирования прокси (умная ссылка)? - PullRequest
2 голосов
/ 11 июля 2020

В настоящее время я работаю над своим академическим c исследованием, в котором я разрабатываю приложение android, реализуя шаблоны проектирования Gang of Four, насколько это возможно (примечание: шаблон GoF является обязательным, это часть исследования, которое я

Теперь я подошел к той части, где я получаю данные из удаленного / Rest API через репозиторий. Я не хочу, чтобы приложение всегда получало одни и те же данные с пульта дистанционного управления, потому что это очень дорого (требует времени, ресурсов, пропускной способности и т. Д. c), как и большинство приложений, я решил добавить механизм кэширования.

В моем предыдущем проекте приложения android я обычно «кэширую» данные, используя базу данных (Room) в сочетании с выделенным полем, чтобы объект кеша оставался в памяти (см. Фрагмент кода ниже).

Но у меня почти заканчивается время (из-за крайнего срока исследования), я хочу больше сосредоточиться на реализации GoF в приложении, которое я разрабатываю, и предпочитаю избегать вещей, связанных с базами данных.

Приведенный ниже код - это фрагмент моего класса репозитория. Когда мне (скажем, ViewModel) нужны пользовательские данные, он вызовет метод getUser() из репозитория.

Inside getUser() метод, я проверю, является ли shouldRefre sh ложным, а объект кеша не равно нулю. После истины он возвращает cacheUser, но если false, то будет вызван метод fetchUser() (интерфейс, предоставляемый библиотекой модернизации). Я считаю, что fetchUser () выполняет очень тяжелую и дорогостоящую задачу (поскольку для этого требуется inte rnet, а процесс зависит от качества сети).

Фрагмент класса Repository.java.

public class AccountRepository {
    private AccountWebservice webservice;
    private User cacheUser;

    public User getUser(String accessToken, int userId, boolean shouldRefresh) {
        if (!shouldRefresh && cacheUser != null) {
            return cacheUser;
        } 

        Call<SinglePayloadResponse<User>> call = webservice.fetchUser(accessToken, userId);
        call.enqueue(new Callback<SinglePayloadResponse<User>>() {
        @Override
        public void onResponse(Call<SinglePayloadResponse<User>> call, Response<SinglePayloadResponse<User>> response) {
            assert response.body() != null;
            cacheUser = response.body().getPayload(); // currently I'm *caching* the response by assign it to cacheUser
            return cacheUser;
        }

        @Override
        public void onFailure(Call<SinglePayloadResponse<User>> call, Throwable t) {

        }
    });
    }
}

Я обнаружил, что шаблон прокси (Smart Proxy Pattern) используется для обработки создания дорогостоящих объектов, как в этом примере ( Использование шаблона проектирования прокси ), как мы видим, ProxyImage был введен, чтобы обернуть настоящий дорогой объект (RealImage), чтобы не перезагружать его снова, если он уже загружен.

Я вижу, что шаблон интеллектуального прокси имеет поведение (например, кеширование), которое мне нравится выполнять sh в это приложение. Интересно, могу ли я реализовать этот шаблон для кеширования ответов (например, данных пользователя, недавно просмотренных продуктов, недавних результатов поиска и других релевантных вещей, которые требуют доступа как можно скорее) из веб-службы в классе репозитория.

Теперь реальный вопрос:

Достаточно ли разумен мой случай, чтобы применить шаблон Smart Proxy? Если да, то как это применить? (Давайте возьмем фрагмент приведенного выше класса репозитория - это мое текущее решение для доступа к пользовательским данным, и мне нужно применить шаблон интеллектуального прокси)

Я все еще пытаюсь изучить 23 каталога шаблона GoF, поскольку у меня есть ограниченное время, ограниченные знания, ограниченная перспектива, мне очень легко упустить что-то и даже важные вещи в шаблоне. Поэтому мы приветствуем любые ответы, рекомендации и разъяснения «моего» или «вашего» недоразумения, спасибо.

1 Ответ

0 голосов
/ 12 июля 2020

Чтобы использовать прокси, вам сначала нужно создать интерфейс. Поскольку вы уже использовали имя «AccountRepository», я назову интерфейс «IAccountRepository

public interface IAccountRepository {
    User getUser(String accessToken, int userId, boolean shouldRefresh);
}

, тогда вы позволите AccountRepository реализовать IAccountRepository и переместить оттуда все logi c, связанные с кешем:

public class AccountRepository implements IAccountRepository {
    private AccountWebservice webservice;

    public User getUser(String accessToken, int userId, boolean shouldRefresh) {
        Call<SinglePayloadResponse<User>> call = webservice.fetchUser(accessToken, userId);
        call.enqueue(new Callback<SinglePayloadResponse<User>>() {
        @Override
        public void onResponse(Call<SinglePayloadResponse<User>> call, Response<SinglePayloadResponse<User>> response) {
            assert response.body() != null;
            cacheUser = response.body().getPayload(); // currently I'm *caching* the response by assign it to cacheUser
            return cacheUser;
        }

        @Override
        public void onFailure(Call<SinglePayloadResponse<User>> call, Throwable t) {

        }
    });
    }
}

теперь вы можете реализовать свой прокси:

public AccountRepositoryCacheProxy implements IAccountRepository {
     private IAccountRepository accountRepository
     public User getUser(String accessToken, int userId, boolean shouldRefresh) {
           if (!userIsInCache(userId) || shouldRefresh) {
                User result = accountRepository.GetUser(accessToken, userId, false);
                addUserInCache(userId, result);
                return result;
           }
           return userFromCache(userid);
     }
}

ваш фактический кеш должен быть чем-то похожим на параллельный словарь String, User.

где бы вы ни находились в вашем коде вам нужен репозиторий учетной записи, вам нужно создать его следующим образом:

 IAccountRepository accountRepository = new AccountRepositoryCacheProxy( new AccountRepository()));

на самом деле система внедрения зависимостей была бы намного лучше.

...