日常中经常会用到策略模式完成业务:这里举例三个功能模块,分别是竣工文档,项目过程和会议文档,这三个都会调用一个通用接口,但是会由前端参数的区别而去调用自己的业务逻辑
对于这种通用接口实现,根据前端传递的参数调用不同业务逻辑,可以按照以下方式设计:
1. 接口定义
设计一个统一的接口入口,参数中包含明确区分模块类型的字段(例如 moduleType),后端根据该字段调用对应模块的业务逻辑。
示例接口定义:
@RestController
@RequestMapping("/document")
public class DocumentController {
@PostMapping("/process")
public ResponseEntity<?> processDocument(@RequestBody DocumentRequest request) {
String moduleType = request.getModuleType();
//也可能会用if-else
switch (moduleType) {
case "completionDocument":
return ResponseEntity.ok(completionDocumentService.process(request));
case "projectProcess":
return ResponseEntity.ok(projectProcessService.process(request));
case "meetingDocument":
return ResponseEntity.ok(meetingDocumentService.process(request));
default:
return ResponseEntity.badRequest().body("Invalid module type");
}
}
}
2. 业务逻辑接口抽象
为了更好的扩展性,可以将每个模块的业务逻辑抽象成一个接口,各模块实现自己的逻辑。
定义接口:
public interface DocumentService {
Object process(DocumentRequest request);
}
模块实现:
@Service
public class CompletionDocumentService implements DocumentService {
@Override
public Object process(DocumentRequest request) {
// 处理竣工文档逻辑
return "Processed Completion Document";
}
}
@Service
public class ProjectProcessService implements DocumentService {
@Override
public Object process(DocumentRequest request) {
// 处理项目过程逻辑
return "Processed Project Process Document";
}
}
@Service
public class MeetingDocumentService implements DocumentService {
@Override
public Object process(DocumentRequest request) {
// 处理会议文档逻辑
return "Processed Meeting Document";
}
}
3. 优化:策略模式
通过 Spring 的策略模式 优化代码,避免在控制器中硬编码 switch。
定义策略注解和工厂类:
创建模块类型枚举:
public enum ModuleType {
COMPLETION_DOCUMENT, PROJECT_PROCESS, MEETING_DOCUMENT
}
模块类型注解:
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface ModuleHandler {
ModuleType value();
}
策略工厂:
@Component
public class DocumentStrategyFactory {
private final Map<ModuleType, DocumentService> strategyMap = new HashMap<>();
@Autowired
public DocumentStrategyFactory(List<DocumentService> strategies) {
for (DocumentService strategy : strategies) {
ModuleHandler annotation = strategy.getClass().getAnnotation(ModuleHandler.class);
if (annotation != null) {
strategyMap.put(annotation.value(), strategy);
}
}
}
public DocumentService getStrategy(ModuleType type) {
return strategyMap.get(type);
}
}
各模块实现:
在各服务类上添加注解:
@Service
@ModuleHandler(ModuleType.COMPLETION_DOCUMENT)
public class CompletionDocumentService implements DocumentService {
@Override
public Object process(DocumentRequest request) {
// 处理竣工文档逻辑
return "Processed Completion Document";
}
}
控制器调用:
@RestController
@RequestMapping("/document")
public class DocumentController {
private final DocumentStrategyFactory strategyFactory;
@Autowired
public DocumentController(DocumentStrategyFactory strategyFactory) {
this.strategyFactory = strategyFactory;
}
@PostMapping("/process")
public ResponseEntity<?> processDocument(@RequestBody DocumentRequest request) {
ModuleType type = ModuleType.valueOf(request.getModuleType().toUpperCase());
DocumentService service = strategyFactory.getStrategy(type);
if (service == null) {
return ResponseEntity.badRequest().body("Invalid module type");
}
return ResponseEntity.ok(service.process(request));
}
}
4. 优点
- 高内聚低耦合:不同模块的业务逻辑分离,便于扩展新模块。
- 可维护性强:使用策略模式,新增模块时无需修改原代码,只需实现
DocumentService并添加注解。 - 统一接口:前端只需调用一个接口,后端根据业务需求分发到不同逻辑。
这种设计可以满足你的需求,并且对未来需求变更具有较好的扩展性。
5.更改
注解在上面的写法中只起到一个作为Map的Key来当身份标识的作用,这里不想用注解可以在枚举中添加属性。
@Getter
@AllArgsConstructor
public enum ModuleType {
PROJECT_PROCESS(1,"项目过程),
MEETING_DOCUMENT(2,"会议文档"),
COMPLETION_DOCUMENT(3,"竣工文档");
private Integer value;
private String desc;
//根据value获取枚举
public static FileNameSchema getEnum(Integer value) {
return Arrays.stream(FileNameSchema.values()).filter(item -> Objects.equals(item.getValue(), value)).findFirst().orElse(null);
}
}
定义接口:
public interface DocumentService {
Integer getIdentity();
Object process(DocumentRequest request);
}
模块实现:
@Service
public class CompletionDocumentService implements DocumentService {
@Override
public Integer getIdentity() {
return ModuleType.COMPLETION_DOCUMENT.getValue();
}
@Override
public Object process(DocumentRequest request) {
// 处理竣工文档逻辑
return "Processed Completion Document";
}
}
@Service
public class ProjectProcessService implements DocumentService {
@Override
public Integer getIdentity() {
return ModuleType.PROJECT_PROCESS.getValue();
}
@Override
public Object process(DocumentRequest request) {
// 处理项目过程逻辑
return "Processed Project Process Document";
}
}
@Service
public class MeetingDocumentService implements DocumentService {
@Override
public Integer getIdentity() {
return ModuleType.MEETING_DOCUMENT.getValue();
}
@Override
public Object process(DocumentRequest request) {
// 处理会议文档逻辑
return "Processed Meeting Document";
}
}
控制器调用:
@RestController
@RequestMapping("/document")
public class DocumentController {
private final Map<Integer, DocumentService> strategyMap = new HashMap<>();
@Resource
private List<DocumentService> strategies;
@PostConstruct
void initStrategyMap() {
for (DocumentService strategy : strategies) {
strategyMap.put(strategy.getIdentity(), strategy);
}
}
public DocumentService getStrategy(FileNameSchema schema) {
return strategyMap.get(schema.getValue());
}
@PostMapping("/process")
public ResponseEntity<?> processDocument(@RequestBody DocumentRequest request) {
ModuleType TypeEnum = ModuleType.getEnum(param.getAttachmentType());
DocumentService documentService = getStrategy(TypeEnum);
if (service == null) {
return ResponseEntity.badRequest().body("Invalid module type");
}
return ResponseEntity.ok(service.process(request));
}
}