博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
模板方法模式
阅读量:4096 次
发布时间:2019-05-25

本文共 3895 字,大约阅读时间需要 12 分钟。

概念

Define the skeleton of an algorithm in an operation,deferring some steps to subclasses.Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm's structure.

定义一个操作中的算法的框架,而将一些步骤延迟到子类中。使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。

实际上是封装了一个固定流程,该流程由几个步骤组成,具体步骤可以由子类进行不同实现,从而让固定的流程产生不同的结果。

非常简单,其实就是类的继承机制,但它却是一个应用非常广泛的模式。

本质:抽象封装流程,具体进行实现

主要解决

当完成一个操作具有固定的流程时,由抽象固定流程步骤,具体步骤交给子类进行具体实现(固定的流程,不同的实现)。

优缺点

优点

  • 封装不变,扩展可变:父类封装了具体流程以及实现部分不变行为,其它可变行为交由子类进行具体实现;
  • 流程由父类控制,子类进行实现:框架流程由父类限定,子类无法更改;子类可以针对流程某些步骤进行具体实现;

缺点

  • 抽象规定了行为,具体负责实现,与通常事物的行为相反,会带来理解上的困难(通俗地说,“父类调用了子类方法”);

使用场景

  • 多个子类有公有的方法,并且逻辑基本相同时;
  • 重要,复杂的算法,可以把核心算法设计为模板方法,周边的相关细节功能则由各个子类实现;
  • 重构时, 是一个经常使用的模式,把相同的代码抽取到父类,然后通过钩子函数约束其行为;

模式讲解

首先来看下 的通用 UML 类图:

模板方法模式

从 UML 类图中,我们可以看到, 主要包含两种角色:

  • 抽象模板(AbstractClass):抽象模板类,定义了一套算法框架/流程;
  • 具体实现(ConcreteClass):具体实现类,对算法框架/流程的某些步骤进行了实现;

以下是 的通用代码:

class Client {    public static void main(String[] args) {        AbstractClass abc = new ConcreteClassA();        abc.templateMehthod();        abc = new ConcreteClassB();        abc.templateMehthod();    }    // 抽象模板类    static abstract class AbstractClass {        protected void step1() {            System.out.println("AbstractClass:step1");        }        protected void step2() {            System.out.println("AbstractClass:step2");        }        protected void step3() {            System.out.println("AbstractClass:step3");        }        // 声明为final方法,避免子类覆写        public final void templateMehthod() {            this.step1();            this.step2();            this.step3();        }    }    // 具体实现类A    static class ConcreteClassA extends AbstractClass {        @Override        protected void step1() {            System.out.println("ConcreateClassA:step1");        }    }    // 具体实现类B    static class ConcreteClassB extends AbstractClass {        @Override        protected void step2() {            System.out.println("ConcreateClassB:step2");        }    }}

:通常把抽象模板类AbstractClass的模板方法templateMethod定义成final类型,避免子类对其覆写,并遵命定义算法结构/流程的语义。

举个例子

例子:小明要炒两道菜:炒豆芽和炒茄子;

分析:炒菜都有固定步骤:洗菜,热锅下油,下菜翻炒,下调料,起锅。由于炒菜流程是固定的,而其中有些步骤对不同的菜而言具备不同的操作,因此可以很好地使用 完成炒菜过程。

具体代码如下:

class Client {    public static void main(String[] args) {        System.out.println("准备炒豆芽");        CookVegetable cookVegetable = new CookBeanSprout();        cookVegetable.cook();        System.out.println();        System.out.println("准备炒茄子");        cookVegetable = new CookEggplant();        cookVegetable.cook();    }    // 抽象模板类:定义炒菜流程    static abstract class CookVegetable {        protected void wash() {            System.out.println("洗菜");        }        protected void pourOil() {            System.out.println("热油下锅");        }        protected void fry() {            System.out.println("下菜翻炒");        }        // 具体调料由菜决定        protected abstract void pourSauce();        // 具体炒菜流程        public final void cook() {            this.wash();            this.pourOil();            this.fry();            this.pourSauce();            System.out.println("起锅吃菜");        }    }    // 豆芽    static class CookBeanSprout extends CookVegetable {        @Override        protected void pourOil() {            System.out.println("热锅少油");        }        @Override        protected void fry() {            System.out.println("快速翻炒");        }        @Override        protected void pourSauce() {            System.out.println("加盐和少量生抽");        }    }    // 茄子    static class CookEggplant extends CookVegetable {        @Override        protected void wash() {            System.out.println("去除头尾,然后用水洗下");        }        @Override        protected void pourOil() {            System.out.println("热锅多油");        }        @Override        protected void pourSauce() {            System.out.println("加盐和鸡精");        }    }}

结果如下:

准备炒豆芽洗菜热锅少油快速翻炒加盐和少量生抽起锅吃菜准备炒茄子去除头尾,然后用水洗下热锅多油下菜翻炒加盐和鸡精

我们根据 ,就可以抽象定义炒菜的流程,然后针对不同的菜品,由其子类对某些炒菜步骤进行具体实现,这样就完成了炒菜过程。

转载地址:http://hwlii.baihongyu.com/

你可能感兴趣的文章
php实现socket(转)
查看>>
PHP底层的运行机制与原理
查看>>
深入了解php底层机制
查看>>
PHP中的stdClass 【转】
查看>>
XHProf-php轻量级的性能分析工具
查看>>
PHP7新特性 What will be in PHP 7/PHPNG
查看>>
比较strtr, str_replace和preg_replace三个函数的效率
查看>>
ubuntu 下编译PHP5.5.7问题:configure: error: freetype.h not found.
查看>>
PHP编译configure时常见错误 debian centos
查看>>
configure: error: Please reinstall the BZip2 distribution
查看>>
OpenCV gpu模块样例注释:video_reader.cpp
查看>>
【增强学习在无人驾驶中的应用】
查看>>
《python+opencv实践》四、图像特征提取与描述——29理解图像特征
查看>>
《python+opencv实践》四、图像特征提取与描述——30Harris 角点检测
查看>>
《python+opencv实践》四、图像特征提取与描述——31 Shi-Tomasi 角点检测& 适合于跟踪的图像特征
查看>>
OpenCV meanshift目标跟踪总结
查看>>
人工神经网络——神经元模型介绍
查看>>
人工神经网络——感知器介绍
查看>>
人工神经网络——反向传播算法(BackPropagation)
查看>>
进程的地址空间概述
查看>>