Поиск в WeChat【Третий принц Ао Бин] Обратите внимание на этого жадного программиста.
эта статьяGitHub github.com/JavaFamilyВключено, и есть полные тестовые площадки, материалы и мой цикл статей для интервью с производителями первой линии.
предисловие
У каждого должен быть опыт собеседования, но процесс собеседования на самом деле очень похож на шаблон проектирования.У каждого раунда интервьюеров есть свои обязанности.Процесс собеседования кандидата на работу похож на процесс запроса клиента.
В серии статей, посвященных шаблонам проектирования, вам уже поделились творческим шаблоном проектирования, и заинтересованные друзья могут перейти к предыдущему обмену. Затем начните делиться тремя типами шаблонов проектирования.поведенческая модельЧто ж, сегодня я хочу поделитьсяМодель цепочки ответственности
контур
определение
Что такое цепочка ответственности? Каково его обоснование?
Разделите отправку и получение запросов, чтобы несколько объектов-получателей имели возможность обработать запрос. Объедините эти получатели в цепочку и передайте запрос по цепочке до тех пор, пока один из получателей в цепочке не сможет его обработать.
Приведенное выше определение взято из книги «Красота шаблонов проектирования».
Давайте посмотрим на официальную иллюстрацию
- Клиент (клиент): создайте цепочку обработчиков и вызовите метод handleRequest для первого объекта цепочки.
- Handle (обработчик): абстрактный класс, предоставляемый фактическому процессору для наследования и последующей реализации метода handleRequest для обработки запроса.
- ConcreteHandler (конкретный обработчик): класс, наследующий обработчик и реализующий метод handleRequst, отвечающий за обработку классов бизнес-логики.Разные бизнес-модули имеют разные ConcreteHandlers.
Глядя на структуру таким образом, она на самом деле относительно проста, но давайте воспользуемся процессом собеседования, чтобы смоделировать цепочку ответственности!
Код
Предположим, теперь я иду в компанию на собеседование, в первый раз я иду в одну сторону, во второй раз иду во вторую сторону, а в третий раз иду напрямую. Как написать этот фиктивный код интервью?
public abstract class Handler {
protected Handler handler;
public void setHandler(Handler handler) {
this.handler = handler;
}
public abstract void handleRequest(Integer times);
}
Прежде всего, мы все еще определяем абстрактный обработчик Handler и добавляем абстрактный метод обработки handleRequest, затем мне нужно только написать конкретный процессор, чтобы он наследовал класс Handler.
public class FirstInterview extends Handler {
@Override
public void handleRequest(Integer times) {
// 条件判断是否是属于当前Handler的处理范围之内,不是则向下传递Handler处理器
if(times ==1){
// 假设这里是处理的业务逻辑代码
System.out.println("第一次面试"+times);
}
handler.handleRequest(times);
}
}
Во-вторых, создайте первый обработчик интервью, внедрите метод handleRequest внутри и оцените, должна ли текущая обработка обрабатывать бизнес-логику или передать ее, если нет. Те же коды второго SecondInterview и FirstInterview в принципе одинаковые, я не буду его выкладывать для вас, просто посмотрите на последний
public class ThreeInterview extends Handler {
@Override
public void handleRequest(Integer times) {
if (times == 3) {
System.out.println("第三次面试"+ times + ",恭喜面试通过,HR会跟你联 系!!!");
}
}
public static void main(String[] args) {
Handler first = new FirstInterview();
Handler second = new SecondInterview();
Handler three = new ThreeInterview();
first.setHandler(second);
second.setHandler(three);
// 第一次面试
first.handleRequest(1);
System.out.println();
// 第二次面试
first.handleRequest(2);
System.out.println();
// 第三次面试
first.handleRequest(3);
System.out.println();
}
}
В этом результате хорошо видно, что по нашим параметрам разные Хендлеры ведут свой бизнес в соответствии со своими обязанностями, что представляет собой цепочку ответственности.
применение рамок
Цепочка ответственности также отражена в исходном коде многих фреймворков. Например, начните изучать SpringMVC вServletFilter
и веснойSpringInterceptorПо сути, здесь используется идея модели цепочки ответственности, которая обеспечивает масштабируемость фреймворка, а также следует принципу открытости-закрытости.
Как общая структура RPC, DUBBO также имеет идею этой цепочки ответственности.
Дать вам вопрос для размышления?
Как только сервис dubbo открыт, в принципе, можно вызвать любой сервис, но в некоторых особых случаях нам нужно открыть сервис, но мы не хотим, чтобы люди, которые не разбираются в бизнесе, вызывали нас случайно.
Например: служба dubbo для изменения инвентаря продуктов, мы разрешаем вызывать только определенные сценарии, такие как размещение заказа, корзина, добавление и изменение продуктов и т. д.
Итак, есть ли способ сделать хорошую работу по перехвату на стороне провайдера и разрешить вызовы только для определенных служб, иначе перехват не позволит выполнить?
Первый способ — добавить имя службы APP_NAME в качестве проверки параметра, что является наиболее распространенным и простым способом.
Второй метод реализует перехватчик DUBBO для выборочной фильтрации вызовов RPC.
Для двух вышеуказанных методов я подробно расскажу, как реализовать второй метод.Каждая компания будет вносить свои специфические изменения на основе существующего исходного кода DUBBO, поэтому второй метод также требует от нас изменить строку, чтобы иметь исходный код dubbo. код.
Сначала измените потребительский перехватчик ConsumerContextFilter.
В качестве примера мы возьмем версию dubbo 2.7.19. Добавьте APP_NAME к вложениям в ConsumerContextFilter, тогда как этот вызов RPC мы можем получить значение, которое мы вставили из вложений.
Что касается приобретения этого APP_NAME, вы можете получить имя службы через System.getProperty("project.name", "")
Здесь я не буду слишком много развивать DUBBO, если у вас есть сильное предложение объяснить. Затем в конце режима проектирования я подробно разберу dubbo, а также ZAB в zookeeper, алгоритм выбора консенсуса и так далее.
Так как CONSUMER заполнил имя сервиса, то в том же Provider нужно написать только ProviderFilter.
Вот базовая реализация того, как обрабатывать перехват каждого вызова RPC, а затем, если вы хотите перехватить этот сервис, вы можете указать этот DubboProviderFilter в фильтре в провайдере или вы можете реализовать его глобально.
Примечание. Если этот фильтр находится в упаковке DUBBO, не ошибитесь.
Примеры реальной трансформации бизнеса
Раз такие идеи есть во фреймворке, то как применить их к бизнес-коду?
Позвольте мне привести Вам пример:
Мы можем отображать детали продукта в модулях, такие как изображение заголовка, информация о продукте, информация о артикуле, адрес доставки, оплата в рассрочку и т. д.
Итак, как собрать для отображения информации о продукте?
public abstract class AbstractDataHandler<T> {
// 处理模块化数据
protected abstract T doRequest(String query) throws Exception;
}
Прежде всего, мы по-прежнему определяем абстрактный обработчик данных, а затем устанавливаем ItemInfoHandler и SkuInfoHandler соответственно, чтобы наследовать абстрактный обработчик.
@Component
public class ItemInfoHandler extends AbstractDataHandler<ItemInfoHandler.ItemInfo> {
@Override
protected ItemInfoHandler.ItemInfo doRequest(String query) {
ItemInfoHandler.ItemInfo info = new ItemInfo();
info.setItemId(123456L);
info.setItemName("测试商品");
return info;
}
@Data
public static class ItemInfo {
private Long itemId;
private String itemName;
}
}
Тот же класс SkuInfoHandler тот же
@Component
public class SkuInfoHandler extends AbstractDataHandler<SkuInfoHandler.SkuInfo> {
@Override
protected SkuInfoHandler.SkuInfo doRequest(String query) {
SkuInfoHandler.SkuInfo info = new SkuInfoHandler.SkuInfo();
info.setSkuId(78910L);
info.setSkuName("测试SKU");
return info;
}
@Data
public static class SkuInfo {
private Long skuId;
private String skuName;
}
}
Наконец, наш тестовый код
@Component
public class DataAggregation {
@Autowired
private SkuInfoHandler skuInfoHandler;
@Autowired
private ItemInfoHandler itemInfoHandler;
public Map convertItemDetail() throws Exception {
Map result = new HashMap();
result.put("skuInfoHandler", skuInfoHandler.doRequest("模拟数据请求"));
result.put("itemInfoHandler",itemInfoHandler.doRequest("模拟数据请求"));
return result;
}
public static void main(String[] args) throws Exception {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
DataAggregation dataAggregation = (DataAggregation) applicationContext.getBean("dataAggregation");
Map map = dataAggregation.convertItemDetail();
System.out.println(JSON.toJSONString(map));
// 打印的结果数据
// {"skuInfoHandler":{"skuId":78910,"skuName":"测试SKU"},"itemInfoHandler":{"itemId":123456,"itemName":"测试商品"}}
}
}
Этот пример на самом деле немного изменен.Вместо того, чтобы передавать процессор, мы используем фактическую бизнес-логику для создания данных каждого модуля в методе convertItemDetail и, наконец, возвращаем данные структуры карты.
На самом деле здесь есть и другой способ записи.Каждый обработчик, который нужно обработать, можно загрузить в контейнер List, а затем циклически вызывать метод doRequest в каждом обработчике.Конечно, это написано для каких-то других бизнес-сценариев .
Прочитав его, вы также обнаружите, что каждый обработчик можно использовать совместно, а логика кода каждого бизнеса очень понятна, и писать такой код очень удобно.
Суммировать
Шаблоны проектирования не статичны, только тот шаблон, который подходит вашему текущему бизнесу, является лучшим шаблоном. Поймите мысли наших предшественников и сами совместите нужные нам шаблоны.
Этот обмен здесь, а затем я поделюсь с вами шаблоном поведенческого проектирования.
Я Ао Бин,Чем больше вы знаете, тем больше вы не знаете, спасибо за ваши таланты:как,собиратьиКомментарий, увидимся в следующий раз!
Статья постоянно обновляется, вы можете искать в WeChat "Третий принц Ао Бин"Прочтите это в первый раз, ответьте [материал] Подготовленные мной материалы интервью и шаблоны резюме крупных заводов первой линии, эта статьяGitHub github.com/JavaFamilyОн был включен, и есть полные тестовые сайты для интервью с крупными заводами.Добро пожаловать в Star.