• Head First设计模式(阅读笔记)-09.模板方法模式


    咖啡和茶的冲泡

    假设咖啡的冲泡过程为把水煮沸--》用沸水泡咖啡--》把咖啡倒入杯子--》加糖和奶,而茶的冲泡过程为把水煮沸--》用沸水泡茶叶--》把茶倒入杯子--》加柠檬。在现有实现的基础上,如何体现更好的封装性?


    public class Coffee{
        // 咖啡冲泡过程
        void prepareRecipe(){
            boilwater();
            brewCoffeeGrinds();
            pourInCup();
            addSugarAndMilk();
        }
    	// 上述方法的具体实现
    }
    
    public class Tea{
        // 茶冲泡过程
        void prepareRecipe(){
            boilwater();
            steepTeaBag();
            pourInCup();
            addLemon();
        }
    	// 上述方法的具体实现
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    模板方法模式

    • 定义了一个算法的步骤,并将一些实现步骤延迟到子类中(即让子类提供某些步骤的实现)
    • 工厂方法是模板方法的特殊版本

    模式表述
    模板方法子类决定如何实现算法中的某些步骤
    策略封装可交换的行为,然后使用委托决定要采用哪一个行为
    工厂方法哪个具体类
    提取相似点

    在两者制作过程中,boilWater方法和pourInCup方法都是一样的,可以抽象放到基类中


    public abstract class CaffeinBeverage{  // 基类
        // 其余代码后续说明
        void boilWater(){...}
    	void pourInCup(){...}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    抽象prepareRecipe方法

    除了上述两个一样的方法,还存在相似点:brewCoffeeGrindsteepTeaBag以及addSugarAndMilkaddLemon是两对差异不大的方法,可以将第一组抽象为brew方法,第二组抽象为addCondiments方法,同样放到基类中


    public abstract class CaffeinBeverage{
        // 声明为final是因为不希望子类去重写该方法
        final void prepareRecipe(){
            boilWater();
            brew();
            pourInCup();
            addCondiments();
        }
        // 声明为抽象,让子类去实现
        abstract void brew();
        abstract void addCondiments();
        
        void boilWater(){...}
    	void pourInCup(){...}
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    开始冲泡

    以冲泡茶为例


    public class Tea extends CaffeinBeverage{
        public void brew(){
            System.out.println("Steeping the tea");
        }
        public void addCondiments(){
            System.out.println("Adding Lemon");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    对模板方法进行挂钩
    • 钩子是一种被声明在抽象类中的方法,它具有空或默认实现
    • 钩子是为了让子类有能力对算法的不同点进行挂钩(由子类决定要不要挂钩)

    public abstract class CaffeinBeverageWithHook{
        final void prepareRecipe(){
            boilWater();
            brew();
            pourInCup();
            if(customerWantsCondiments){
            	addCondiments();
    		}
        }
        // 钩子,子类可以选择覆盖
        boolean customerWantsCondiments(){
    		return true;
        }
        // 其余代码一致
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    排序鸭子


    模板方法排序

    Java Arrays类中提供了模板方法进行排序,其中Sort是模板方法,并且**CompareTo延迟到子类去实现**


    // 之所以定义为static是因为数组无法继承,也就无法通过xxx.sort使用排序,而是Arrays.sort(xxx)
    public static void sort(Object[] a){
        Object[] aux = (Object[])a.clone();
        merge(aux, a, 0, a.length, 0);
    }
    private static void merge(Object[] src, Object[] dest, int low, int high, int off){
        for(int j = i; j > low && ((Comparable)dest[j - 1]).compareTo((Comparable)dest[j]) > 0; j--){
            swap(dest, j, j-1);  // 在Arrays类中定义了
        }
        return;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    鸭子类

    public class Duck implements Comparable{  // 实现Comparable接口中的compareTo方法,
        int weight;
        public int compareTo(Object o){
            Duck otherDuck = (Duck)o;
            if(this.weight < otherDuck.weight){
                return -1;
            }else if(this.weight == otherDuck.weight){
                return 0;
            }else{
                return 1;
            }
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    参考

    Head First 设计模式-模板方法模式

    设计模式-模板模式

  • 相关阅读:
    Halcon Deep Learning Classification 和 C# 客户端调用模型进行识别
    深度学习案例分享 | 手写数字识别 - PyTorch 实现
    传奇GOM引擎登录器配置教程
    基于vue框架的4S店汽车维修保养管理系统28a7y(程序+源码+数据库+调试部署+开发环境)系统界面在最后面。
    【大模型】代码生成能力验证
    Golang 自定义时间结构体支持Json&Gorm
    【预约观看】Ambire 智能钱包 AMA 活动第四期即将举行
    ubuntu 安装 微服务 dapr
    led护眼灯真的护眼吗?推荐双十一可闭眼盲入的LED灯
    Linux线程池
  • 原文地址:https://blog.csdn.net/qq_41398418/article/details/128169652