Некоторое время назад я реорганизовал функцию пакетного просмотра в системе компании, используя параллельное программирование Java для асинхронной обработки и механизм оптимистической блокировки базы данных для обработки многопоточного параллельного обновления данных. Среди них бизнес-обработка проверки партии включает в себя различные типы задач, которые обрабатываются в соответствии с различными бизнес-методами, такими как перемещение складов, передача экспресс-доставки, добавление подарков, удаление подарков, разделение заказов, отклонение партии, аннулирование партии и т. д. ., среди которых использование режима стратегии.
если еще образец
if ("BATCH_CHANGE_WAREHOUSE".equals(taskType)) {
//批量转仓逻辑
} else if ("BATCH_CHANGE_SHIPPING".equals(taskType)) {
//批量转快递逻辑
} else if ("BATCH_REPLACE_ORDER_GOODS".equals(taskType)) {
//批量替换订单商品逻辑
} else if ("BATCH_DELETE_ORDER_GOODS".equals(taskType)) {
//批量删除订单商品逻辑
} else if ("BATCH_ADD_MEMO".equals(taskType)) {
//批量添加备注逻辑
} else {
//任务类型未知
System.out.println("任务类型无法处理");
}
Кажется, что мысль ясна, и ветки if и else тоже очень ясны, но не кажется ли вам, что код раздут и хлопотно поддерживать, особенно когда другие люди приходят, чтобы забрать банк, нет желания прочитайте это. На данный момент вам нужно использовать шаблон стратегии, чтобы исключить if else и выполнить простой рефакторинг!
режим стратегии
1. Сначала абстрагируйте бизнес-процессор
public abstract class InspectionSolver {
public abstract void solve(Long orderId, Long userId);
public abstract String[] supports();
}
2. Поместите бизнес-процессор и поддерживаемые им типы в контейнер Map — один из наиболее часто используемых контейнеров в java.
@Component
public class InspectionSolverChooser implements ApplicationContextAware{
private Map<String, InspectionSolver> chooseMap = new HashMap<>();
public InspectionSolver choose(String type) {
return chooseMap.get(type);
}
@PostConstruct
public void register() {
Map<String, InspectionSolver> solverMap = context.getBeansOfType(InspectionSolver.class);
for (InspectionSolver solver : solverMap.values()) {
for (String support : solver.supports()) {
chooseMap.put(support,solver);
}
}
}
private ApplicationContext context;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.context=applicationContext;
}
}
Здесь при запуске приложения все процессоры типа InspectionSolver в контейнере spring загружаются и помещаются в контейнер карты InspectionSolverChooser. Обратите внимание, что это тип InspectionSolver, поэтому определенные процессоры должны наследовать InspectionSolver, за которыми следует загружаемый контейнер Spring, поэтому определенные процессоры должны быть помещены в контейнер Spring (аннотация @Component не может быть меньше)
3. Определите разные процессоры
@Component
public class ChangeWarehouseSolver extends InspectionSolver {
@Override
public void solve(Long orderId, Long userId) {
System.out.println("订单"+orderId+"开始进行批量转仓了。。");
}
@Override
public String[] supports() {
return new String[] {InspectionConstant.INSPECTION_TASK_TYPE_BATCH_CHANGE_WAREHOUSE};
}
}
@Component
public class ChangeShippingSolver extends InspectionSolver{
@Override
public void solve(Long orderId, Long userId) {
System.out.println("订单"+orderId+"开始进行转快递了。。");
}
@Override
public String[] supports() {
return new String[] {InspectionConstant.INSPECTION_TASK_TYPE_BATCH_CHANGE_SHIPPING};
}
}
@Component
public class ReplaceOrderGoodsSolver extends InspectionSolver{
@Override
public void solve(Long orderId, Long userId) {
System.out.println("订单"+orderId+"开始进行替换商品了");
}
@Override
public String[] supports() {
return new String[]{InspectionConstant.INSPECTION_TASK_TYPE_BATCH_REPLACE_ORDER_GOODS};
}
}
4. Тестовый класс
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes=Application.class)// 指定spring-boot的启动类
public class InspectionTest {
@Autowired
private InspectionSolverChooser chooser;
@Test
public void test() throws Exception{
//准备数据
String taskType = InspectionConstant.INSPECTION_TASK_TYPE_BATCH_CHANGE_WAREHOUSE;
Long orderId = 12345L;
Long userId = 123L;
//获取任务类型对应的solver
InspectionSolver solver = chooser.choose(taskType);
if (solver == null) {
throw new RuntimeException("任务类型暂时无法处理!");
}
//调用不同solver的方法进行处理
solver.solve(orderId,userId);
}
}
В тестовом классе я исключаю, что может быть длинным секцией, удаляет разные процессор процессора задач из селекторного инспектора, а затем вызывает его решить () метод для выполнения обработки задач, конечно, разные процессоры вызовываются в разных Решить () методы достигаются.