템플릿 메소드 패턴은 모든 패턴 중에서 가장 일반적인 패턴 중 하나이며 상속을 기반으로 하는 코드 재사용의 기본 기술이며 관계가 없습니다. 따라서 템플릿 메소드 패턴의 클래스 구조 다이어그램에는 상속 관계만 존재한다.
AbstractClass: 추상 클래스, 템플릿 메소드를 정의하고 구현합니다. 이 템플릿 메서드는 알고리즘의 뼈대를 정의하고 논리적 구성 요소 단계는 해당 추상 작업의 하위 클래스로 연기됩니다.
ConcreteClass: 상위 클래스에서 정의한 하나 이상의 추상 메서드를 구현합니다.
장점
템플릿 방식을 사용하여 동일한 처리 논리를 가진 코드를 추상 상위 클래스에 넣으면 코드의 재사용성을 향상시킬 수 있습니다.
다양한 코드를 다양한 하위 클래스에 넣고 하위 클래스를 확장하여 새로운 동작을 추가하여 코드 확장성을 향상시킵니다.
상위 클래스에서 변경되지 않은 동작을 작성하고, 하위 클래스의 중복 코드를 제거하고, 열기 및 닫기 원칙을 준수하는 좋은 코드 재사용 플랫폼을 제공합니다.
단점
클래스 수가 증가함에 따라 각 추상 클래스를 구현하려면 하위 클래스가 필요하므로 클래스 수가 늘어나고 복잡성이 증가합니다. 클래스 수의 증가는 간접적으로 시스템 구현의 복잡성을 증가시킵니다. 상속 관계에는 고유한 단점이 있습니다. 상위 클래스가 새로운 추상 메서드를 추가하면 모든 하위 클래스가 이를 변경해야 합니다.
상위 클래스 관점: 알고리즘의 변경되지 않은 부분을 한 번에 구현하고 변수 부분은 하위 클래스 구현에 맡깁니다.
하위 클래스 관점: 각 하위 클래스에서 공통 부분을 추출하여 나옵니다. 코드 중복을 피하기 위해 이를 공통 상위 클래스에 집중시킵니다.
템플릿 메서드 패턴의 목적은 하위 클래스가 템플릿에 대한 고정 메서드의 특정 단계를 확장하거나 구현할 수 있도록 하는 것입니다. 이는 고정 알고리즘 집합입니다. , 고정 알고리즘의 특정 알고리즘 단계는 하위 클래스를 통해 확장될 수 있습니다.
전략 패턴은 일련의 알고리즘을 해당 클래스로 캡슐화한 것이며, 이러한 클래스는 동일한 인터페이스를 구현하고 서로 교체될 수 있습니다. 알고리즘의 캡슐화에 초점을 맞춘 또 다른 패턴
이 있습니다. 바로 템플릿 메소드 패턴입니다. 클래스 다이어그램을 보면 전략 패턴과 템플릿 메소드 패턴의 차이점은 단지 별도의 캡슐화 클래스가 있다는 것뿐입니다.
컨텍스트는 템플릿 메소드와 다릅니다. 모드의 차이점은 템플릿 메소드 모드에서는 호출 알고리즘의 본체가 추상 상위 클래스에 있는 반면, 전략 모드에서는 호출 알고리즘의 본체가 있다는 것입니다. 호출 알고리즘은 캡슐화 클래스 Context에 캡슐화됩니다. 추상 전략 전략은 일반적으로 인터페이스의 목적은 사양을 정의하는 것이며 일반적으로 논리를 포함하지 않습니다. 사실 이것은 일반적인 구현일 뿐이지만 실제 프로그래밍에서는 특정 전략 구현 클래스 간에 필연적으로 동일한 로직이 있기 때문에 코드 중복을 피하기 위해 추상 클래스를 사용하여 전략 역할을 수행하고 이를 캡슐화하는 경우가 많습니다. 따라서 공개 코드 내에서는 많은 애플리케이션 시나리오에서 일반적으로 전략 패턴에서 템플릿 메서드 패턴의 그림자를 볼 수 있습니다.
코드 케이스
@Slf4j public abstract class AbstractPayCallbackTemplate { /** * 异步回调业务 * * @return */ public String asyncCallBack() { // 1. 支付回调验证参数 Map<String, String> verifySignatureMap = verifySignature(); // 2. 参数验证成功,写入日志中.. payLog(verifySignatureMap); String analysisCode = verifySignatureMap.get("analysisCode"); if (!analysisCode.equals("200")) { return resultFail(); } // 3. 执行回调异步相关逻辑 return asyncService(verifySignatureMap); } /** * 支付回调验证参数 * * @return */ protected abstract Map<String, String> verifySignature(); /** * 使用多线程异步写入日志 * * @param verifySignatureMap */ @Async void payLog(Map<String, String> verifySignatureMap) { log.info(">>>>>>>>>>第二步 写入payLog........"); } /** * 每个子类需要实现 实现业务解析操作 * * @return */ protected abstract String asyncService(Map<String, String> verifySignatureMap); /** * 异步返回结果.. * * @return */ protected abstract String resultSuccess(); /** * 异步返回失败 * * @return */ protected abstract String resultFail(); }
구체적인 구현 템플릿 클래스
@Log4j2 public class AliPayCallbackTemplate extends AbstractPayCallbackTemplate { @Override protected Map<String, String> verifySignature() { //>>>>假设一下为银联回调报文>>>>>>>>>>>>>>>> log.info(">>>>>第一步 解析支付宝据报文.....verifySignature()"); Map<String, String> verifySignature = new HashMap<>(); verifySignature.put("price", "1399"); verifySignature.put("orderDes", "充值永久会员"); // 支付状态为1表示为成功.... verifySignature.put("aliPayMentStatus", "1"); verifySignature.put("aliPayOrderNumber", "201910101011"); // 解析报文是否成功 200 为成功.. verifySignature.put("analysisCode", "200"); return verifySignature; } @Override protected String asyncService(Map<String, String> verifySignatureMap) { log.info(">>>>>第三步asyncService()verifySignatureMap:{}", verifySignatureMap); String paymentStatus = verifySignatureMap.get("aliPayMentStatus"); if (paymentStatus.equals("1")) { String aliPayOrderNumber = verifySignatureMap.get("aliPayOrderNumber"); log.info(">>>>orderNumber:{aliPayOrderNumber},已经支付成功 修改订单状态为已经支付..."); } return resultSuccess(); } @Override protected String resultSuccess() { return "ok"; } @Override protected String resultFail() { return "fail"; } } @Slf4j public class UnionPayCallbackTemplate extends AbstractPayCallbackTemplate { @Override protected Map<String, String> verifySignature() { //>>>>假设一下为银联回调报文>>>>>>>>>>>>>>>> log.info(">>>>>第一步 解析银联数据报文.....verifySignature()"); Map<String, String> verifySignature = new HashMap<>(); verifySignature.put("price", "1399"); verifySignature.put("orderDes", "充值永久会员"); // 支付状态为1表示为成功.... verifySignature.put("paymentStatus", "1"); verifySignature.put("orderNumber", "201910101011"); // 解析报文是否成功 200 为成功.. verifySignature.put("analysisCode", "200"); return verifySignature; } @Override protected String asyncService(Map<String, String> verifySignatureMap) { log.info(">>>>>第三步asyncService()verifySignatureMap:{}", verifySignatureMap); String paymentStatus = verifySignatureMap.get("paymentStatus"); if (paymentStatus.equals("1")) { String orderNumber = verifySignatureMap.get("orderNumber"); log.info(">>>>orderNumber:{orderNumber},已经支付成功 修改订单状态为已经支付..."); } return resultSuccess(); } @Override protected String resultSuccess() { return "success"; } @Override protected String resultFail() { return "fail"; } }
템플릿을 가져오는 팩토리 모드
public class TemplateFactory { private final static Map<String, AbstractPayCallbackTemplate> templateMap = new ConcurrentHashMap<>(); static { templateMap.put("aliPay", new AliPayCallbackTemplate()); templateMap.put("unionPay", new UnionPayCallbackTemplate()); } public static AbstractPayCallbackTemplate getPayCallbackTemplate(String templateId) { AbstractPayCallbackTemplate payCallbackTemplate = (AbstractPayCallbackTemplate) templateMap.get(templateId); return payCallbackTemplate; } }
테스트 클래스
public class Test { public static void main(String[] args) { AbstractPayCallbackTemplate aliPay = TemplateFactory.getPayCallbackTemplate("aliPay"); String s = aliPay.asyncCallBack(); System.out.println(s); } }
위 내용은 Java 디자인 패턴 템플릿 방법 예시 분석의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!