设计模式之模板模式
定义: 定义一个操作的算法骨架,而将一些步骤延迟到子类中。Template method 使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤
应用场景:
- 当你想让客户端只扩展算法的特定步骤时,而不是整个算法或其结构时
- 当你有几个类包含几乎形同的算法,但有一些细微的差异时
优点:
- 你可以让客户端只覆盖大型算法的某些部分,从而减少算法其他部分发生的更改对他们的影响
- 你可以将重复的代码拖放到超类中
可以参考:
- javax.servlet.http.HttpServlet
- org.springframework.web.servlet.mvc.AbstractController
今天我们说下模板模式在实际项目中使用的场景之一,话补多少直接上代码
@Slf4j
@Service
public abstract class AbstractPayPatternService {
public String doPay(String orderNo, String pattern) {
checkData(null);
Map<String,Object> map = verifySignature(null);
String result = executeService(map);
writeLog(null);
return "SUCCESS";
}
public void checkData(Object object){
log.info("参数验证");
}
public final void writeLog(Object object){
log.info("异步写入操作日志信息");
}
protected abstract Map<String,Object> verifySignature(Object object);
protected abstract String executeService(Map<String,Object> map);
}
现在我们去编写相关业务的执行代码,这里实现 InitializingBean 主要是想换一种方式标记当前类,当然你也可以使用@Service(“XXXXX”)来标记当类的唯一标识,这里只做一个实现类,如果其他的支付方式 可以自己另行创建实现
@Slf4j
@Service
public class WechatPayServiceImpl extends AbstractPayPatternService implements InitializingBean {
@Override
protected Map<String, Object> verifySignature(Object object) {
log.info("微信方支付参数认证和签名");
return new HashMap<>(0);
}
@Override
protected String executeService(Map<String, Object> map) {
log.info("微信支付接口调用和业务处理");
return "OK";
}
@Override
public void afterPropertiesSet() throws Exception {
SpringUtil.STATE_MAP.put("wechatPay","wechatPayServiceImpl");
}
}
@Slf4j
@Component
public class SpringUtil implements ApplicationContextAware {
private static ApplicationContext context;
public static Map<String,String> STATE_MAP = new HashMap<>();
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
SpringUtil.context = applicationContext;
}
public static ApplicationContext getContext(){
return context;
}
public static Object getBean(String name){
return getContext().getBean(name);
}
public static <T> T getBean(Class<T> clazz){
return getContext().getBean(clazz);
}
public static <T> T getBean(String name,Class<T> clazz){
String clsName = STATE_MAP.get(name);
return getContext().getBean(clsName,clazz);
}
}
```java
@RestController
@RequestMapping("pay")
public class PayPatternController {
@GetMapping("pay")
public String payOrder(String payPattern){
AbstractPayPatternService bean = SpringUtil.getBean(payPattern, AbstractPayPatternService.class);
String result = bean.doPay("O9876", payPattern);
return result;
}
}
标记类方法 也可以参考上一篇的状态模式篇 小编尽量在以后的创作中使用不同的实现方式
|