• 模板方法模式


    问题

    A模块 和 B模块 完全分开,互相独立,但是重复和相似的代码太多,不便扩展。

    解决思路

    将重复或相似的代码抽取出来,做成公共的功能,不同的控制就去扩展公共功能,也就是:将相似的运算步骤看做算法的骨架作为父类,具体的不同的步骤放到子类中实现。

    模板方法

    • 定义

      定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。

      父类实现的就是不变的方法和算法的骨架,而需要变化的地方,都通过抽象方法,而子类就通过实现这些抽象方法完成特定的功能。
    • 结构
      • AbstractClass:抽象类(父类)。定义算法的骨架和原语操作,还可以提供算法通用的实现。(必有)
      • ConcreteClass:具体类(子类)。重定义父类的原子操作,完成特定子类的功能。(必有)
      • 具体的AbstractClass操作:辅助的公共功能。父类实现某些公共功能,给子类使用。
      • 钩子操作:子类选择地覆写父类的具体的操作,已提供新的实现来扩展功能。
      • 原语操作:父类的抽象方法,需要子类来实现。(必有)
      • Factory Method:父类中,需要某些对象的实例,可以用工厂模式获取,具体的构建对象的实现延迟到子类中。
        •      /**
                * 抽象类
              **/
              public abstract class AbstractClass
              {
                  // 原语操作,放到子类去实现
                  public abstract void PrimitiveOperation1();
                  public abstract void PrimitiveOperation2();
          
                   // 模板方法,定义逻辑的骨架。
                  public void TemplateMethod()
                  {
                      PrimitiveOperation1();
                      PrimitiveOperation2();
          match(); }
            
          // 具体的操作
          public void match()
             {
          // 公共的实现
          }
                  // 工厂模式:创建某个对象,这里用Object代替
                  public abstract Object createObject();
          }
          /** * 具体类,实现了抽象类中的原语步骤 **/ public class ConcreteClass extends AbstractClass {
             @Override
          public void PrimitiveOperation1() { //具体实现 }
          @Override
          public void PrimitiveOperation2() { //具体实现 }

          // 钩子操作
          @Override
             public void match()
             {
          // 子类的实现
          }
          }

    java的回调与模板方法

    • 定义

      模板方法:在于让其他类来扩展或具体实现在模板(父类)中固定的算法骨架中的某些算法步骤。在标准的模板方法实现中,主要使用继承的方式,使父类在运行期间可以调用到子类中。

      在java开发中,还有另一个方法可以实现同样的功能------java回调:通过回调在接口中定义的方法,调用到具体的实现类中的方法。在这种实现中,可以不写子类,而是使用匿名内部类来实现回调方法。
    • 结构
      • 回调接口:把所有需要扩展的方法定义出来。
      • 模板类:
        • 不再是抽象类,所有抽象方法删除。
        • 模板方法,添加一个参数,传入回调接口。
        • 在模板方法实现中,除了模板中固定的实现外,所有可以被扩展的方法,都应通过回调接口进行调用。
      • 客户端:需要使用匿名内部类来实现回调接口,并实现其中想要扩展的方法。
                 /**
                  * 回调接口
                **/
                public interface InterfaceCallback
                {
                    // 需要扩展的方法
                    public void PrimitiveOperation1();
                    public void PrimitiveOperation2();
             
                    // 工厂模式:创建某个对象,这里用Object代替
                    public Object createObject();
        
                }
        
                 /**
                  * 模板类
                **/
                public class TemplateClass
                {
                    // 模板方法,添加回调接口的入参。
                    public void TemplateMethod(InterfaceCallback callback)
                    {
                        callback.PrimitiveOperation1();
                        callback.PrimitiveOperation2();
                        match();
                    }
             
                    // 具体的操作
                    public void match()
                  { 
                       // 实现
                    }
                }
        
                 /**
                  * 客户端
                **/
                public class Client
                {
                    // 测试模板方法。
                    public void TestTemplateMethod()
                    {
                        TemplateClass template = new TemplateClass();
                        template.TemplateMethod(new InterfaceCallback(){
                            
                            public void PrimitiveOperation1(){
                                 //具体实现
                            }
                            
                            public void PrimitiveOperation2(){
                                //具体实现
                            }
                         
                            public Object createObject(){
                                //具体实现
                            }
                        });
                    }
                }                            
                

    模板方法实现方式:继承/回调 总结

    • 回调方式更灵活,因为java是单继承,使用继承方式,子类就不能继承其他对象,而回调基于接口。
    • 继承方式,抽象方法和实现的类的关系是在编译时期静态决定的,是类级关系;回调方式,是在运行期间动态决定的,是对象级关系。
    • 继承方式更简单点,因为父类提供实现方法,子类不想扩展,不用管;回调方式,回调的接口需要将扩展的所有方法都定义进去,则,实现时,不管扩不扩展,都得实现。

    模板方法优缺点

    • 优点是实现代码复用:把子类的公共功能提取到模板中实现。
    • 缺点是算法骨架不容易升级:模板和子类是非常耦合的,如果变更算法骨架,则相应的子类也可能相应的变化,所以抽取算法骨架,尽量确定不会变化的部分才放到模板中。
  • 相关阅读:
    网络流强化-HDU 3338-上下界限制最大流
    OJ测试数据追溯方法
    网络流强化-HDU2732
    网络流强化-UVA10480
    网络流强化-HDU4280
    网络流强化-POJ2516
    POJ 3281 网络流 拆点保证本身只匹配一对食物和饮料
    动态规划-递推-HDU2048
    java List<Item> its=new ArrayList<Item>(); Map按value中的某字段排序
    Spring jar下载地址:
  • 原文地址:https://www.cnblogs.com/zhuhaichan/p/7852205.html
Copyright © 2020-2023  润新知