zoukankan      html  css  js  c++  java
  • 【图解设计模式三】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:

    因为接口只能负责声明抽象方法,而抽象类不仅负责声明抽象方法,还负责具体实现模板方法对抽象方法进行调用,即使用抽象类可以在抽象方法的声明阶段确定调用的流程。
    
  • 相关阅读:
    动态代理练习2全站压缩流输出[response动态代理]
    动态代理练习3自定义数据库连接池[connection动态代理]
    类加载器
    Mysql中的数据类型对应于Java中什么数据类型
    使用网上流传的一个数据库连接池在Proxy.newProxyInstance处引起 java.lang.ClassCastException 问题的解决方法
    动态代理练习1全站字符编码过滤[request动态代理]
    用cocos2dx将helloworld实现出来了
    多线程的自动管理(线程池)
    互斥对象
    多线程的自动管理(定时器)
  • 原文地址:https://www.cnblogs.com/zzzz76/p/14417186.html
Copyright © 2011-2022 走看看