1 基础知识
定义:定义了一个算法的骨架并允许子类为一个或多个步骤提供实现。特征:模板方法使得子类可以在不改变算法结构的前提下重新定义某些步骤。
使用场景:一次性实现一个算法的不变部分,将可变的行为留给子类实现;各子类中公共的行为被提取出来并集中到一个公共的父类中从而避免代码重复。
优点:提高复用性、扩展性;符合开闭原则。缺点:类数目增加;增加了系统实现的复杂度;模板方法主要通过继承实现,继承本身的缺点:如果父类添加新的抽象方法,所有子类都要实现一遍。
2 代码示例
使用场景:在教育网站制作课程时,对于PPT等一些素材是必备的而一些如手记则可能有的课程有些没有。
抽象的课程类:
public abstract class ACourse { protected final void makeCourse(){ this.makePPT(); this.makeVideo(); //是否写手记交由钩子方法实现 if(needWriteArticle()){ this.writeArticle(); } this.packageCourse(); } //final方法子类不可以进行覆盖 final void makePPT(){ System.out.println("制作PPT"); } final void makeVideo(){ System.out.println("制作视频"); } final void writeArticle(){ System.out.println("编写手记"); } //钩子方法 protected boolean needWriteArticle(){ return false; } //包装方法 abstract void packageCourse(); }
具体课程类:DesignPatternCourse
public class DesignPatternCourse extends ACourse { @Override void packageCourse() { System.out.println("提供课程Java源代码"); } @Override //重写父类方法,有手记 protected boolean needWriteArticle() { return true; } }
具体课程类:
public class FECourse extends ACourse { @Override void packageCourse() { System.out.println("提供课程的前端代码"); System.out.println("提供课程的图片等多媒体素材"); } @Override protected boolean needWriteArticle() { return this.needWriteArticleFlag; } }
应用层:
public class Test { public static void main(String[] args) { System.out.println("后端设计模式课程start---"); ACourse designPatternCourse = new DesignPatternCourse(); designPatternCourse.makeCourse(); System.out.println("后端设计模式课程end---"); System.out.println("前端课程start---"); ACourse feCourse = new FECourse(); feCourse.makeCourse(); System.out.println("前端课程end---"); } }
这样就显示后端课程有手记,前端课程没有手记。那么再复杂化一下:前端课程中有些课程没有,有些有手记,如果还按照上面的方法那么就会造成前端课程中都有或者没有了。对前端课程进行修改:
public class FECourse extends ACourse { //声明一个变量通过构造器方式开放给应用层。 private boolean needWriteArticleFlag = false; @Override void packageCourse() { System.out.println("提供课程的前端代码"); System.out.println("提供课程的图片等多媒体素材"); } public FECourse(boolean needWriteArticleFlag) { this.needWriteArticleFlag = needWriteArticleFlag; } @Override protected boolean needWriteArticle() { return this.needWriteArticleFlag; } }
在应用层:这样把权限开放给了应用层。
public class Test { public static void main(String[] args) { System.out.println("前端课程start---"); ACourse feCourse1 = new FECourse(true); feCourse.makeCourse(); System.out.println("前端课程end---"); System.out.println("前端课程start---"); ACourse feCourse2 = new FECourse(false); feCourse.makeCourse(); System.out.println("前端课程end---"); } }
其类关系图如下:
0