Шесть основных принципов шаблонов проектирования Android

Принцип единой ответственности SRP

По отношению к классу есть только одна причина для его изменения

Открытый Закрытый принцип OCP

Изменения реализуются посредством расширений, а не путем модификации существующих кодов Старайтесь не добавлять новые реализации через наследование и т.п.

Принцип замены Лисков LSP

Пока может появиться родительский класс, может появиться и подкласс, в основном в реализации и наследовании.

Принцип инверсии зависимостей DIP

Особая форма разделения, при которой модули высокого уровня не зависят от модулей низкого уровня, а модули высокого уровня зависят не от деталей, а от абстракций.

Принцип разделения интерфейсов ISP

Пусть клиент зависит от как можно меньшего количества интерфейсов. Разделение интерфейса, единый интерфейс

Принцип Деметры LDP

Принцип наименьшего известного, объект имеет наименьшее знание о других объектах

Практическое применение

Разработайте структуру сетевых запросов, функции включают в себя: сетевой запрос, кеширование, анализ возвращаемых данных и т. д.

1. Первый этап:

        Все функции написаны в Activity

  Проблема: Дизайна нет вообще.Слишком много повторяющихся кодов при звонке в нескольких местах.Если модифицировать то нужно модифицировать второй этап во всех местах.

2. Второй этап:

        Инкапсулируйте запрос в класс инструмента HttpUtils.

  Проблема: класс HttpUtils слишком раздут и делает слишком много вещей.Запросы, кеши и т. д. все связаны в этом классе, и обработка анализа возвращаемых данных может быть обработана только внешними вызывающими объектами и т. д.

3. Третий этап:

  1. Извлеките функцию кеша в SpHttpCache (в настоящее время кеш кэшируется только в sp) ( принцип единой ответственности )
  2. Создайте интерфейс HttpCallBack, непосредственно управляйте обратным вызовом успеха или неудачи запроса и поместите обработку открытого события возвращенного результата в запрос HttpUtils, например анализ данных и совместимость возвращаемых данных в разных форматах.

  Проблема: просто инкапсулировать какую-то общую логику в класс инструмента, масштабируемости нет вообще, коды запросов все свалены в одну кучу, слишком много параметров вызова, и может потребоваться передать больше дюжины параметров в метод построения, такой как метод запроса и параметры запроса, тайм-аут повторного подключения, период тайм-аута, поддержка файлов cookie и т. д. Если вам нужно расширить параметры, вам нужно добавить больше конструкторов

4. Четвертый этап:   

  1. В HttpUtils измените параметры для цепочки вызовов, вызывайте параметры, которые нужны вызывающему, и не вызывайте, если они им не нужны.
  2.     public static HttpUtils with(Context context){
            return new HttpUtils(context);
        }
    
        private HttpUtils(Context context) {
            mHttpRequest = new OKHttpRequest();
            mParams = new HashMap<>();
            this.mContext = context;
        }
    
        public HttpUtils get(){
            mType = TYPE_GET;
            return this;
        }
    
        public HttpUtils param(String key,Object value){
            mParams.put(key,value);
            return this;
        }
    
        public HttpUtils url(String url){
            this.mUrl = url;
            return this;
        }
    
        public <T> void request(final HttpCallBack<T> callback){
            // 在此做一些异常判断,如url校验等
            mHttpRequest.get(mContext,mUrl,mParams,callback,true);
        }
  3. Выполните проверку параметров перед запросом
  4. Инкапсулировать запрос в класс OKHttpRequest ( принцип единой ответственности )

  Вопрос: Если вы хотите использовать другие сетевые запросы, вы можете только изменить вызов HttpUtils, или вы можете переключать сетевые запросы в любое время, как с этим быть

5. Пятый этап:   

  1. Создайте интерфейс IHttpRequest и определите такие методы, как get и post в интерфейсе.
  2. Класс запроса OKHttpRequest реализует интерфейс интерфейса IHttpRequest.
  3. Добавьте параметр IHttpRequest в HttpUtils, и вызывающая сторона сможет передать подкласс, который реализует интерфейс IHttpRequest, посредством цепочек вызовов.
    private IHttpRequest mHttpRequest;
    ……
    public HttpUtils httpRequest(IHttpRequest httpRequest){
        mHttpRequest = httpRequest;
        return this;
    }

    // 可在application设置默认请求
    public static void initHttpRequest(IHttpRequest httpRequest) {
        mInitHttpRequest = httpRequest;
    }


    public <T> void request(final HttpCallBack<T> callback){
        if(mHttpRequest == null){
            mHttpRequest = mInitHttpRequest;
        }
        // 异常判断
        mHttpRequest.get(mContext,mUrl,mParams,callback,true);
    }

    4. Если вы хотите добавить новый сетевой запрос, вам нужно всего лишь создать класс, реализующий IHttpRequest, и вызвать метод httpRequest(), чтобы установить требуемый сетевой запрос при вызове

        Принцип открытия и закрытия: когда необходимо добавить новые сетевые запросы, нет необходимости изменять код HttpUtils, необходимо добавлять только новые классы, которые открыты для расширения и закрыты для модификации.

         Принцип подстановки Лисков: там, где появляется родительский класс IHttpRequest, может появиться подкласс OKHttpRequest, HttpUtils.initHttpRequest(new OKHttpRequest());

         Принцип инверсии зависимостей: высокоуровневые HttpUtils зависят не от низкоуровневых деталей (OKHttpRequest), а от низкоуровневых абстракций (IHttpRequest).

        Принцип Dimiter: В MainActivity используйте HttpUtils для выполнения сетевых запросов.Неважно, как это в нем реализовано.Вы только знаете, какие параметры нужно передать и получить обратно конечный результат.На остальное плевать

     5. То же самое верно для класса кеша, кеша памяти, кеша диска (базы данных, жесткого диска)

        Часто используемые интерфейсы могут кэшироваться в памяти и на диске, а редко используемые интерфейсы могут кэшироваться непосредственно на диске.

Supongo que te gusta

Origin blog.csdn.net/weixin_42277946/article/details/131031429
Recomendado
Clasificación