• 【图解设计模式三】Template Method 模式


    将具体处理交给子类

    一、知识概述

    Template Method 设计模式是指在父类中定义处理流程的框架,在子类中实现具体处理。其主要包含两种主要的角色。

    • AbstractClass: 为抽象类,不仅负责实现模板方法,还负责声明在模板方法中所使用到的抽象方法。
    • ConcreteClass: 为具体类,负责具体实现AbstractClass角色中声明的抽象方法。

    二、示例程序

    以下为实现了Template Method模式的示例程序,这段示例程序的主要作用是,将字符和字符串循环显示5次,二者分别采用不同的显示格式。

    类图示例

    程序清单

    流程

    /**
     * 声明需求方法的抽象类,并使用所声明的方法进行具体处理
     */
    public abstract class AbstractDisplay {
        // 方法声明
        public abstract void open();
        public abstract void print();
        public abstract void close();
    
        // 方法实现
        public final void display() {
            open();
            for (int i = 0; i < 5; i++) {
                print();
            }
            close();
        }
    }
    
    /**
     * 测试程序行为的类 将字符和字符串循环显示5次
     */
    public class Main {
        public static void main(String[] args) {
            AbstractDisplay d1 = new CharDisplay('H');
            AbstractDisplay d2 = new StringDisplay("Hello, world");
            AbstractDisplay d3 = new StringDisplay("你好,世界");
            d1.display();
            d2.display();
            d3.display();
        }
    }
    
    

    实现

    /**
     * 实现了open、print、close方法的类
     */
    public class CharDisplay extends AbstractDisplay {
        private char ch;
    
        public CharDisplay(char ch) {
            this.ch = ch;
        }
    
        public void open() {
            System.out.print("<<");
        }
    
        public void print() {
            System.out.print(ch);
        }
    
        // 这里是方法区的继承,那么实例化之后会是怎么样呢
        public void close() {
            System.out.println(">>");
        }
    }
    
    /**
     * 实现了open、print、close方法的类
     */
    public class StringDisplay extends AbstractDisplay {
        private String string;
        private int width;
    
        public StringDisplay(String string) {
            this.string = string;
            this.width = string.getBytes().length;
        }
    
    
        public void open() {
            printLine();
        }
    
        public void print() {
            System.out.println("|" + string + "|");
        }
    
        public void close() {
            printLine();
        }
    
        private void printLine() {
            System.out.print("+");
            for (int i = 0; i < width; i++) {
                System.out.print("-");
            }
            System.out.println("+");
        }
    }
    

    三、课后习题

    问题1:

    java.io.InputStream类使用了Template Method 模式,请参考JDK找出其子类需要实现的方法。

    回答1:

    在子类中需要实现的方法:public abstract in read() throws IOException
    该方法会被java.io.InputStream中的模板方法read(byte[] b, int off, int len)循环调用。
    

    问题2:

    示例程序中AbstractDisplay的模板方法,使用了修饰符final,why?

    回答2:

    public是必要的,为了对外提供接口;final虽然非必要,但是其能够限制方法被子类重写(Override),使程序更加的规范化。
    

    问题3:

    如果相让抽象类中的open、print、close方法,可以被父子类和同包下的类调用,而不能被其他类调用,需要怎么做?

    回答3:

    将方法的访问权限由public改成protected
    

    问题4:

    Java 当中的接口和抽象类很相似,接口同样也是声明抽象方法的集合。为什么在Template Method模式中,无法使用接口来扮演AbstractClass角色?

    回答4:

    因为接口只能负责声明抽象方法,而抽象类不仅负责声明抽象方法,还负责具体实现模板方法对抽象方法进行调用,即使用抽象类可以在抽象方法的声明阶段确定调用的流程。
    
  • 相关阅读:
    Service、chkconfig命令
    mongoDB 入门
    HTTP 缓存
    MIME类型记录
    CSS3 动画 思维导图
    部署Seafile服务
    AngularJS 学习笔记
    Bootstrap3 学习笔记
    CSS 弹性盒
    传送门(portal)
  • 原文地址:https://www.cnblogs.com/zzzz76/p/14417186.html
Copyright © 2020-2023  润新知