模板方法模式

基本介绍
1) 模板方法模式(Template Method Pattern),又叫模板模式(Template Pattern),在一个抽象类公开定义了执行它的方法的模板。它的子类可以按需要重写方法 实现,但调用将以抽象类中定义的方式进行。

2) 简单说,模板方法模式 定义一个操作中的算法的骨架,而将一些步骤延迟到子 类中,使得子类可以不改变一个算法的结构,就可以重定义该算法的某些特定 步骤
3) 这种类型的设计模式属于行为型模式。

模式结构

​
AbstractClass(抽象类):在抽象类中定义了一系列基本操作(PrimitiveOperations),这些基本操作可以是
具体的,也可以是抽象的,
每一个基本操作对应算法的一个步骤,在其子类中可以重定义或实现这些步骤。同时,在抽象类中实现了一个模板
方法(Template Method),用于定义一个算法的框架,模板方法不仅可以调用在抽象类中实现的基本方法,也可
以调用在抽象类的子类中实现的基本方法,还可以调用其他对象中的方法。

ConcreteClass(具体子类):它是抽象类的子类,用于实现在父类中声明的抽象基本操作以完成子类特定算法的
步骤,也可以覆盖在父类中已经实现的具体基本操作。

​
 //抽象类,表示豆浆
    public abstract class SoyaMilk {
        //模板方法, make , 模板方法可以做成final , 不让子类去覆盖.
        final void make() {
            select();
            addCondiments();
            soak();
            beat();
            
        }
        
        //选材料
        void select() {
            System.out.println("第一步:选择好的新鲜黄豆  ");
        }
        
        //添加不同的配料, 抽象方法, 子类具体实现
        abstract void addCondiments();
        
        //浸泡
        void soak() {
            System.out.println("第三步, 黄豆和配料开始浸泡, 需要3小时 ");
        }
        
        void beat() {
            System.out.println("第四步:黄豆和配料放到豆浆机去打碎  ");
        }
}
public class RedBeanSoyaMilk extends SoyaMilk {
	
	@Override
	void addCondiments() {
		System.out.println(" 加入上好的红豆 ");
	}
	
}


public class PeanutSoyaMilk extends SoyaMilk {
	@Override
	void addCondiments() {
		System.out.println(" 加入上好的花生 ");
	}
	
}
public class Client {
	
	public static void main(String[] args) {
		//制作红豆豆浆
		
		System.out.println("----制作红豆豆浆----");
		SoyaMilk redBeanSoyaMilk = new RedBeanSoyaMilk();
		redBeanSoyaMilk.make();
		
		System.out.println("----制作花生豆浆----");
		SoyaMilk peanutSoyaMilk = new PeanutSoyaMilk();
		peanutSoyaMilk.make();
	}
	
}
模板方法模式的钩子方法
1) 在模板方法模式的父类中,我们可以定义一个方法,它默认不做任何事,子类可以 视情况要不要覆盖它,该方
法称为“钩子”。
 2) 还是用上面做豆浆的例子来讲解,比如,我们还希望制作纯豆浆,不添加任何的配 料,请使用钩子方法对前
面的模板方法进行改造 

注意:子类覆盖父类后,子类的实例父类的方法就不用了。

public class PureSoyaMilk extends SoyaMilk{
	
	@Override
	void addCondiments() {
		//空实现
	}
	
	@Override
	boolean customerWantCondiments() {
		return false;
	}
	
}
//抽象类,表示豆浆
public abstract class SoyaMilk {
	
	//模板方法, make , 模板方法可以做成final , 不让子类去覆盖.
	final void make() {
		
		select();
		if(customerWantCondiments()) {
			addCondiments();
		}
		soak();
		beat();
		
	}
	
	//选材料
	void select() {
		System.out.println("第一步:选择好的新鲜黄豆  ");
	}
	
	//添加不同的配料, 抽象方法, 子类具体实现
	abstract void addCondiments();
	
	//浸泡
	void soak() {
		System.out.println("第三步, 黄豆和配料开始浸泡, 需要3小时 ");
	}
	
	void beat() {
		System.out.println("第四步:黄豆和配料放到豆浆机去打碎  ");
	}
	
	//钩子方法,决定是否需要添加配料
	boolean customerWantCondiments() {
		return true;
	}
}
模板方法模式的注意事项和细节
1) 基本思想是:算法只存在于一个地方,也就是在父类中,容易修改。需要修改算 法时,只要修改父类的模板方
法或者已经实现的某些步骤,子类就会继承这些修改 
2) 实现了最大化代码复用。父类的模板方法和已实现的某些步骤会被子类继承而直接 使用。
3) 既统一了算法,也提供了很大的灵活性。父类的模板方法确保了算法的结构保持不 变,同时由子类提供部分步
骤的实现。
 4) 该模式的不足之处:每一个不同的实现都需要一个子类实现,导致类的个数增加, 使得系统更加庞大
5) 一般模板方法都加上final关键字, 防止子类重写模板方法. 
6) 模板方法模式使用场景:当要完成在某个过程,该过程要执行一系列步骤 ,这一 系列的步骤基本相同,但其
个别步骤在实现时 可能不同,通常考虑用模板方法模 式来处理

适用环境
在以下情况下可以考虑使用模板方法模式:

对一些复杂的算法进行分割,将其算法中固定不变的部分设计为模板方法和父类具体方法,而一些可以改变的细节由其子类来实现。即:一次性实现一个算法的不变部分,并将可变的行为留给子类来实现。
各子类中公共的行为应被提取出来并集中到一个公共父类中以避免代码重复。
需要通过子类来决定父类算法中某个步骤是否执行,实现子类对父类的反向控制。
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值