wordpress 单本小说站,网站优化公司排名深圳,wordpress 获取id,网站开发前端就业前景委派模式 文章目录 委派模式1.简述**应用场景****优缺点****业务场景示例** 2.类图3.具体实现3.1.自定义注解3.2.定义抽象委派接口3.3.定义具体执行者3.4.定义委派者(统一管理委派任务)3.5.定义委派者管理类 4.测试4.1.controller层4.2.测试不同场景4.2.1.测试生产部门计算费用…委派模式 文章目录 委派模式1.简述**应用场景****优缺点****业务场景示例** 2.类图3.具体实现3.1.自定义注解3.2.定义抽象委派接口3.3.定义具体执行者3.4.定义委派者(统一管理委派任务)3.5.定义委派者管理类 4.测试4.1.controller层4.2.测试不同场景4.2.1.测试生产部门计算费用4.2.2.测试财务部门计算费用4.2.3.测试各种类型传值 1.简述 委派模式是一种负责任务的调度和分配模式类似于代理模式但更注重结果而非过程。它可以被视为一种特殊情况下的静态代理的全权代理但并不属于GOF 23种设计模式之一而是归类为行为型模式。 委派模式在Spring框架中广泛应用其中最常见的例子是DispatcherServlet它充分利用了委派模式的特性。 在Spring框架中DispatcherServlet是一个核心组件负责接收HTTP请求并将其分发给相应的处理器Controller进行处理。DispatcherServlet利用了委派模式的特性来实现请求的转发和处理。 具体来说DispatcherServlet接收到HTTP请求后根据请求的信息如URL、请求方法等会将请求委派给相应的处理器进行处理。这个委派的过程就是典型的委派模式应用。 在Spring中DispatcherServlet并不直接处理请求而是通过HandlerMapping确定请求对应的处理器Controller然后委派给对应的Controller进行处理。处理完成后再由DispatcherServlet负责返回响应给客户端。 这种设计使得Spring的Web应用具有良好的灵活性和可扩展性。开发者可以根据自己的需求定制不同的HandlerMapping和Controller而DispatcherServlet作为统一的入口负责请求的委派和响应的处理使得整个Web应用的架构更加清晰和易于维护。 应用场景
委派模式适用于以下场景
当需要实现表现层与业务层之间的松耦合时委派模式能够提供一个良好的解决方案。在需要编排多个服务之间的调用时特别是像责任链模式这样的情况下委派模式尤为适用。当需要再封装一层服务查找和调用时委派模式也是一种常见的选择。
优缺点
优点
隐藏实现对内部实现进行了封装使得调用方不必关心具体的实现细节增强了系统的安全性和稳定性。易于扩展通过委派模式可以方便地添加新的服务或功能而不会影响到已有的代码。简化调用调用方只需要知道委派对象而不需要知道具体的执行细节降低了系统的复杂度和维护成本。
缺点
膨胀和管理难度与静态代理相似随着具体执行类和委派类的扩展代码容易膨胀难以管理需要谨慎设计和维护。
业务场景示例
在关务系统中费用计算是一个关键功能。不同部门可能采用不同的计算方式。为了应对这种多样性系统需要根据不同部门的要求动态选择合适的费用计算算法以确保费用的准确性和合规性。
在这样的场景下可以借助委派模式来实现动态选择合适的计算算法。下面我们以Spring Boot版本的委派模式为例来展示其具体实现。
2.类图 3.具体实现
3.1.自定义注解
import java.lang.annotation.*;Documented
Inherited
Target({ElementType.TYPE})
Retention(RetentionPolicy.RUNTIME)
public interface Delegate {/*** 执行任务类型*/String type () default ;
}
3.2.定义抽象委派接口
/*** 委派任务通用处理接口*/
public interface DelegateHandlerR,T {/*** 抽象处理方法* param t 处理任务参数*/R process(T t);
}3.3.定义具体执行者
/*** 财务部门委派类* author 13723* version 1.0* 2024/1/7 14:52*/
Delegate(type finance)
Component
public class FinanceDepartmentDelegate implements DelegateHandlerResultObject, BigDecimal{private static final Logger logger LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());/*** 财务部门处理将数据加上税费* param s 处理任务参数* return*/Overridepublic ResultObject process(BigDecimal s) {ResultObject instance ResultObject.createInstance(true);BigDecimal res BigDecimal.ZERO;if (s ! null) {res s.add(new BigDecimal(300));instance.setData(res);}instance.setMessage(财务部门处理数据结束);logger.error(财务部门处理数据结束处理前{}处理后{},s,res);return instance;}
}/*** 生产部门委派类* author 13723* version 1.0* 2024/1/7 14:44*/
Delegate(type product)
Component
public class ProductionDepartmentDelegate implements DelegateHandlerResultObject, BigDecimal {private static final Logger logger LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());/*** 生产部门处理将数据重新计算* param s 处理任务参数* return*/Overridepublic ResultObject process(BigDecimal s) {ResultObject instance ResultObject.createInstance(true);BigDecimal res BigDecimal.ZERO;if (s ! null) {res s.multiply(new BigDecimal(1.6));instance.setData(res);}instance.setMessage(生产部门处理数据结束);logger.error(生产部门处理数据结束处理前{}处理后{},s,res);return instance;}
}
3.4.定义委派者(统一管理委派任务)
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.type.filter.AnnotationTypeFilter;
import org.springframework.util.CollectionUtils;import java.lang.invoke.MethodHandles;
import java.util.*;/*** 委派角色管理类* author 13723* version 1.0* 2024/1/7 14:58*/
Delegate
public class DelegateManager extends DelegatePatternConfiguration {private static final Logger logger LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());/*** 存放具体委派角色类型* k-具体委派类型* v-具体任务角色*/private MapString, ListDelegateHandler handlerMap;/*** 存放委派模式中的各种真正执行任务的角色* 分组放* param iHandlerList*/public void setHandlerMap(ListDelegateHandler iHandlerList) {handlerMap scanHandlers(iHandlerList);}/*** 将具体的委派角色 获取进行统一管理* param handlerList 具体实现委派的类集合* return 存放委派*/private MapString, ListDelegateHandler scanHandlers(ListDelegateHandler handlerList) {ClassPathScanningCandidateComponentProvider scanner new ClassPathScanningCandidateComponentProvider(false);scanner.addIncludeFilter(new AnnotationTypeFilter(Delegate.class));MapString, ListDelegateHandler handlerMap new HashMap();for (DelegateHandler handler : handlerList) {Class? targetClass handler.getClass();if (hasDutyAnnotation(targetClass)) {String type getTypeAnnotationValue(targetClass);handlerMap.computeIfAbsent(type, key - new ArrayList()).add(handler);}}return handlerMap;}/*** 判断该类是否是 使用使用了Delegate注解* param clazz 类名称* return true使用了*/private boolean hasDutyAnnotation(Class? clazz ) {return AnnotationUtils.findAnnotation(clazz, Delegate.class) ! null;}/*** 判断使用了的注解Delegate 是否填写了类型* param clazz* return*/private String getTypeAnnotationValue(Class? clazz) {Delegate dutyAnnotation AnnotationUtils.findAnnotation(clazz, Delegate.class);if (dutyAnnotation null) {throw new IllegalStateException(Delegate annotation not found for class: clazz);}return dutyAnnotation.type();}/*** 根据类型 委派具体执行任务的角色* param type 任务类型* param t 传递参数* return 执行后 最终返回结果*/public R, T R process(String type, T t) {ListDelegateHandler handlers handlerMap.get(type);R result null;if (!CollectionUtils.isEmpty(handlers)) {// 注意 这里需要考虑多个执行角色问题遇到多个相同类型执行角色考虑使用责任链别再此模式上死磕。for (DelegateHandlerR, T handler : handlers) {result handler.process(t);}}else {throw new RuntimeException(no match delegate class !);}return result;}
}
3.5.定义委派者管理类
/*** 将 委派模式管理类 注入到Spring中* author 13723* version 1.0* 2024/1/7 15:16*/
Configuration
public class DelegatePatternConfiguration {private static final Logger logger LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());Beanpublic DelegateManager delegateManager(ListDelegateHandler handlers) {// 创建对象 会获取全部使用注解的类将其注入到对应map集合中DelegateManager delegateManager new DelegateManager();delegateManager.setHandlerMap(handlers);return delegateManager;}
}
4.测试
4.1.controller层
import com.hrfan.java_se_base.config.ResultObject;
import com.hrfan.java_se_base.pattern.decorator_pattern.config.DecorateManager;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.*;import javax.annotation.Resource;
import java.lang.invoke.MethodHandles;
import java.math.BigDecimal;
import java.util.Objects;/*** 委派模式测试类* author 13723* version 1.0* 2024/1/7 15:20*/
RestController
RequestMapping(/v1/delegate)
public class DelegateTestController {Resourceprivate DelegateService service;private static final Logger logger LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());ResourceDelegateManager manager;PostMapping(/test)public ResultObject test(RequestBody DelegateMoneyParams params){ResultObject instance ResultObject.createInstance(false);instance.setMessage(计算失败);Objects.requireNonNull(params);if (StringUtils.isNotBlank(params.getType())){switch (params.getType()){case a:instance manager.process(product, params.getTotal());return instance;case b:instance manager.process(finance, params.getTotal());return instance;default:return instance;}}return instance;}
}
4.2.测试不同场景
4.2.1.测试生产部门计算费用 4.2.2.测试财务部门计算费用 4.2.3.测试各种类型传值