• 设计模式模板方法


    template method模式:将部分的特殊实现交给子类

    场景:

    (1) 我们有多种优惠策略

    (2) 不同的优惠策略在计算价格的时候,有一些是通用的基础逻辑

    (3) 然后,每种优惠策略 还有一些是自己 比较特殊的价格计算的逻辑

    不用模板方法的代码实现:

    我们比如说,有3中优惠的方式,

    第一种折扣计算器类DiscountCalculator1,里面有方法calculate,方法实现 有一个通用的计算逻辑,还有优惠计算器1的特殊计算逻辑;

    分别还有,

    第二种折扣计算器类DiscountCalculator2,里面有方法calculate,方法实现 有一个通用的计算逻辑,还有优惠计算器2的特殊计算逻辑;

    第二种折扣计算器类DiscountCalculator3,里面有方法calculate,方法实现 有一个通用的计算逻辑,还有优惠计算器3的特殊计算逻辑;

    然后,我们在main方法中去调用它们,

        public static void main(String[] args) {
            DiscountCalculator1 calculator1 = new DiscountCalculator1();
            calculator1.calculate();
    
            DiscountCalculator2 calculator2 = new DiscountCalculator2();
            calculator2.calculate();
    
            DiscountCalculator3 calculator3 = new DiscountCalculator3();
            calculator3.calculate();
        }

    输出如下:

    通用的计算逻辑
    优惠计算器1的特殊计算逻辑
    通用的计算逻辑
    优惠计算器2的特殊计算逻辑
    通用的计算逻辑
    优惠计算器3的特殊计算逻辑
    
    Process finished with exit code 0

    那么这里,如果不用设计模式的话,有一个问题,就是说 这个三种优惠方式计算器里面,都有一段通用计算逻辑,其实是完全相同的代码,但是完全相同的一段代码,给通过复制粘贴的方式,放到了不同的类里去,那么一旦说,那个通用的计算的计算逻辑 要修改,就涉及到多个类都要去修改那个代码,如果你一旦忘了修改某个类中的那段代码,后果不堪设想;而且到了后期,几乎没人记得清楚,那段通用逻辑代码放在了多少个类中,如果要排查,需要将很多类重新读一遍代码,这就是垃圾代码,扩展性,维护性,很烂。所以这个情况下,我们必须要用设计模式。

    使用模板方法的代码实现:

    这个时候,我们要这么来玩,

    我们先定义一个接口DiscountCalculator,这个接口中定义了一个方法void calculate()即可。当然,这个接口肯定是要定义的,因为我们要面向接口去开发的嘛!

    然后,定义一个抽象类作为基础类AbstractDiscountCalculator implement DiscountCalculator,

    在抽象的基础类中,定义一个方法private void commonCalculate(),其中封装了一段通用的计算逻辑;

    还有一个protected abstract void specificCalculate();,这个是没有实现的,因为它是一个抽象方法;

    最后,还要重写接口中的对外提供的调用方法public void calculate(),其中,先执行commonCalculate()这段通用的计算逻辑,再执行特殊的计算逻辑specificCalculate();

    那么,在具体的实现类中,比如DiscountCalculator1 extends AbstractDiscountCalculator,我们只需实现父类中抽象方法speificCalculate()的具体实现逻辑,优惠计算器1的特殊计算逻辑即可。

    代码如下:

    public class TemplateMethodPatternDemo {
    
        public static void main(String[] args) {
            DiscountCalculator calculator1 = new DiscountCalculator1();
            calculator1.calculate();
    
            DiscountCalculator calculator2 = new DiscountCalculator2();
            calculator2.calculate();
    
            DiscountCalculator calculator3 = new DiscountCalculator3();
            calculator3.calculate();
        }
    
        public interface DiscountCalculator {
            void calculate();
        }
    
        /**
         * 模板方法实现的精华所在
         */
        public static abstract class AbstractDiscountCalculator implements DiscountCalculator {
    
            public void calculate(){
                // 完成通用的计算逻辑
                commonCalculate();
                // 完成特殊的计算逻辑
                specificCalculate();
            }
    
            private void commonCalculate(){
                System.out.println("通用的计算逻辑");
            }
    
            protected abstract void specificCalculate();
        }
    
        public static class DiscountCalculator1 extends AbstractDiscountCalculator{
            public void specificCalculate(){
                System.out.println("优惠计算器1的特殊计算逻辑");
            }
        }
    
        public static class DiscountCalculator2 extends AbstractDiscountCalculator{
            public void  specificCalculate(){
                System.out.println("优惠计算器2的特殊计算逻辑");
            }
        }
    
        public static class DiscountCalculator3 extends AbstractDiscountCalculator{
            public void  specificCalculate(){
                System.out.println("优惠计算器3的特殊计算逻辑");
            }
        }
    
    }

    在这里面的很好的设计就是,通用的计算逻辑,全部给抽出来放在抽象父类AbstractDiscountcalculator中的commonCalculate()方法这个地方,然后,特殊的计算逻辑,定义成抽象方法specificCalculate(),父类不实现,交给子类,比如DiscountCalculator1 extends AbstractDiscountCalculator,子类继承父类之后,子类里面去覆盖实现父类中的这个特殊的计算逻辑。这样的话,对于不同策略优惠的计算器来说,它们通用的计算逻辑没有重复在各个具体的实现中,而是抽取到抽象的父类里面去了,只有这么一块;然后每个子类里面分别去实现自己自己特殊的计算逻辑即可。而这个时候,我们如果要把通用的计算逻辑修改一下,只需要在抽象的父类这一个类里面修改就可以了,也就是说,模板方法这个模式,就是把多个类里面 通用的逻辑 抽象到一个抽象父类里面去,然后,再在各个子类里面去实现它们特有的一个逻辑,在抽象父类里面,对外提供的方法,会定义清楚什么时候去执行通用的计算逻辑,什么时候去执行这个特殊的计算逻辑,特殊的计算逻辑这个方法,是给定义成抽象方法,留给子类去覆盖的,这样就通过模板方法模式,定义一个抽象方法,完美解决了重复性代码的问题。

     总结:

    模板方法设计模式,这个应该是,最高频使用的设计模式,这个高频到了,我都不用在这里举个什么例子,因为在任何一个系统中,一定会出现说,多个类中,其实都有相同的代码,此时就可以使用模板方法设计模式,然后将多个类中通用的设计模式,抽取到一个父类中去。那么什么叫做模板方法呢,其实就是父类里面定义成抽象方法,就是所谓的模板方法,因为这个需要子类去具体实现抽象的方法,只是一个模板,它并没有实现,模板的实现是通过子类去实现的。

  • 相关阅读:
    Gitlab + Gitlab runner + Window powershell
    python 连接SAP 代码
    【翻译】 For OData For C# play on RESTier
    SAP -熟练使用T-Code SHD0
    SAP MM- BAPI_PO_CHANGE 更新PO version 信息(version management)
    SAP PP- OPK8生产订单打印 配置Smart form.
    SAP Smart Form 无法通过程序自定义默认打印机问题解决
    SAP APO-主数据设置
    SAP APO-PP / DS
    SAP APO-供需匹配
  • 原文地址:https://www.cnblogs.com/HarryVan/p/16381524.html
Copyright © 2020-2023  润新知