Принцип единой ответственности SRP
По отношению к классу есть только одна причина для его изменения
Открытый Закрытый принцип OCP
Изменения реализуются посредством расширений, а не путем модификации существующих кодов Старайтесь не добавлять новые реализации через наследование и т.п.
Принцип замены Лисков LSP
Пока может появиться родительский класс, может появиться и подкласс, в основном в реализации и наследовании.
Принцип инверсии зависимостей DIP
Особая форма разделения, при которой модули высокого уровня не зависят от модулей низкого уровня, а модули высокого уровня зависят не от деталей, а от абстракций.
Принцип разделения интерфейсов ISP
Пусть клиент зависит от как можно меньшего количества интерфейсов. Разделение интерфейса, единый интерфейс
Принцип Деметры LDP
Принцип наименьшего известного, объект имеет наименьшее знание о других объектах
Практическое применение
Разработайте структуру сетевых запросов, функции включают в себя: сетевой запрос, кеширование, анализ возвращаемых данных и т. д.
1. Первый этап:
Все функции написаны в Activity
Проблема: Дизайна нет вообще.Слишком много повторяющихся кодов при звонке в нескольких местах.Если модифицировать то нужно модифицировать второй этап во всех местах.
2. Второй этап:
Инкапсулируйте запрос в класс инструмента HttpUtils.
Проблема: класс HttpUtils слишком раздут и делает слишком много вещей.Запросы, кеши и т. д. все связаны в этом классе, и обработка анализа возвращаемых данных может быть обработана только внешними вызывающими объектами и т. д.
3. Третий этап:
- Извлеките функцию кеша в SpHttpCache (в настоящее время кеш кэшируется только в sp) ( принцип единой ответственности )
- Создайте интерфейс HttpCallBack, непосредственно управляйте обратным вызовом успеха или неудачи запроса и поместите обработку открытого события возвращенного результата в запрос HttpUtils, например анализ данных и совместимость возвращаемых данных в разных форматах.
Проблема: просто инкапсулировать какую-то общую логику в класс инструмента, масштабируемости нет вообще, коды запросов все свалены в одну кучу, слишком много параметров вызова, и может потребоваться передать больше дюжины параметров в метод построения, такой как метод запроса и параметры запроса, тайм-аут повторного подключения, период тайм-аута, поддержка файлов cookie и т. д. Если вам нужно расширить параметры, вам нужно добавить больше конструкторов
4. Четвертый этап:
- В HttpUtils измените параметры для цепочки вызовов, вызывайте параметры, которые нужны вызывающему, и не вызывайте, если они им не нужны.
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); }
- Выполните проверку параметров перед запросом
- Инкапсулировать запрос в класс OKHttpRequest ( принцип единой ответственности )
Вопрос: Если вы хотите использовать другие сетевые запросы, вы можете только изменить вызов HttpUtils, или вы можете переключать сетевые запросы в любое время, как с этим быть
5. Пятый этап:
- Создайте интерфейс IHttpRequest и определите такие методы, как get и post в интерфейсе.
- Класс запроса OKHttpRequest реализует интерфейс интерфейса IHttpRequest.
- Добавьте параметр 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. То же самое верно для класса кеша, кеша памяти, кеша диска (базы данных, жесткого диска)
Часто используемые интерфейсы могут кэшироваться в памяти и на диске, а редко используемые интерфейсы могут кэшироваться непосредственно на диске.