场景: (1)我们有多种优惠策略 (2)不同的优惠策略在计算的价格的时候,有一些通用的基础逻辑 (3)每种优惠策略还有一些是自己特殊的价格计算的逻辑

1.常规

  1. package com.example.demo.pattern.template;
  2. /**
  3. * 不用模式的实现
  4. * @author chenchao
  5. *
  6. */
  7. public class WithoutTempalteMethodPatternDemo {
  8. public static void main(String[] args) {
  9. DiscountCalculator1 calculator1 = new DiscountCalculator1();
  10. calculator1.calculate();
  11. DiscountCalculator2 calculator2 = new DiscountCalculator2();
  12. calculator2.calculate();
  13. DiscountCalculator3 calculator3 = new DiscountCalculator3();
  14. calculator3.calculate();
  15. // 有一个问题
  16. // 就是说,这个三种优惠方式计算器里面,都有一段通用的计算逻辑,是完全相同的代码
  17. // 但是相同的一段代码,给通过复制粘贴的方式,放到了不同的类里去
  18. // 一旦说,那段通用的计算逻辑,要修改,就涉及到多个类都要去修改那个代码
  19. // 如果你一旦忘了修改某个类中的那段代码,后果不堪设想
  20. // 而且到了后期,几乎没人记得清楚,那段通用逻辑代码放在了多少个类中,如果要排查,需要将很多类重新读一遍代码
  21. // 这就是垃圾代码,扩展性,维护性,很烂
  22. }
  23. public static class DiscountCalculator1 {
  24. public void calculate() {
  25. System.out.println("通用的计算逻辑,修改了一下");
  26. System.out.println("优惠计算器1的特殊计算逻辑");
  27. }
  28. }
  29. public static class DiscountCalculator2 {
  30. public void calculate() {
  31. System.out.println("通用的计算逻辑,修改了一下");
  32. System.out.println("优惠计算器2的特殊计算逻辑");
  33. }
  34. }
  35. public static class DiscountCalculator3 {
  36. public void calculate() {
  37. System.out.println("通用的计算逻辑");
  38. System.out.println("优惠计算器3的特殊计算逻辑");
  39. }
  40. }
  41. }

2.模板模式

  1. package com.example.demo.pattern.template;
  2. /**
  3. * 使用了模板方法模式
  4. *
  5. * @author chenchao
  6. */
  7. public class TemplateMethodPatterDemo {
  8. public static void main(String[] args) {
  9. DiscountCalculator calculator1 = new DiscountCalculator1();
  10. calculator1.calculate();
  11. DiscountCalculator calculator2 = new DiscountCalculator2();
  12. calculator2.calculate();
  13. DiscountCalculator calculator3 = new DiscountCalculator3();
  14. calculator3.calculate();
  15. }
  16. public interface DiscountCalculator {
  17. void calculate();
  18. }
  19. /**
  20. * 模板方法实现的精华所在
  21. *
  22. * @author chenchao
  23. */
  24. public static abstract class AbstractDiscountCalculator implements DiscountCalculator {
  25. @Override
  26. public void calculate() {
  27. // 完成通用的计算逻辑
  28. commonCalculate();
  29. // 完成特殊的计算逻辑
  30. specificCalculate();
  31. }
  32. private void commonCalculate() {
  33. System.out.println("通用的计算逻辑,修改了一下");
  34. }
  35. protected abstract void specificCalculate();
  36. }
  37. public static class DiscountCalculator1 extends AbstractDiscountCalculator {
  38. @Override
  39. public void specificCalculate() {
  40. System.out.println("优惠计算器1的特殊计算逻辑");
  41. }
  42. }
  43. public static class DiscountCalculator2 extends AbstractDiscountCalculator {
  44. @Override
  45. public void specificCalculate() {
  46. System.out.println("优惠计算器2的特殊计算逻辑");
  47. }
  48. }
  49. public static class DiscountCalculator3 extends AbstractDiscountCalculator {
  50. @Override
  51. public void specificCalculate() {
  52. System.out.println("优惠计算器3的特殊计算逻辑");
  53. }
  54. }
  55. }

3.说明

常用模式之一,对于我们而言喜欢把通用逻辑封装成一个方法,需要用到就引用。相比模板设计模式基于抽象类设计把通用逻辑放到抽象类,每个实现都集成他,这样可读性很好,很好维护,相对于增加代码量扩展性,可读性更好。