您的位置:首页 > 编程语言 > Java开发

Java设计模式之模板方法模式

2016-08-18 14:50 363 查看

Java设计模式之模板方法模式

1.什么是模板方法模式(Template Method) 为算法的执行定义了一个统一的框架,其中的某些具体实现方法需要他在子类中去完成,每个子类所做的事情可能都不一样,而子类可以在不改变这个框架的同时去完成该算法的某个具体步骤,这就是我们所说的模板模式。

生活中的模板:

银行办理业务,1、进门取号 2、填写单据 3、等待叫号 4、窗口办理,对于这四个规则,所有
来办理业务的人都需要遵循这四种规则,但是在四个规则中规则2填写单据去是需要顾客填写的,
因为银行他并不知道顾客具体要办理什么样的业务,所以,他只能让顾客自己去填写这样的单据,
这样银行就是为顾客定义了一个模板。


2.如何实现模板方法模式

1.首先需要一个抽象基类,为所有子类提供一个算法框架
2.定义一个模板方法,封装所有子类共同遵循的算法框架
3.将对应的步奏写入模板方法中,将所有共同方法声明为私有的或者final方法,为了隐藏实现细节
4.将所有并不知道具体实现什么的方法设置为抽象方法,为了让他的子类去实现具体细节
5.所有子类的具体实现


细节:钩子方法实现:加入一个判断条件,询问用户是否需要执行该操作,提供一个默认或空的实现,让子类去选择是否挂钩,

模板方法模式的实现要素:

准备一个抽象类,将部分逻辑以具体方法的形式实现,然后声明一些抽象方法交由子类实现剩余逻辑,用钩子方法给予子类更大的灵活性,最后将方法汇总构成一个不可改变的模板方法。

3.模板方法模式的特点

优点:封装性好,、复用性好、屏蔽细节、便于维护

缺点:继承的局限性

4.模板方法模式在项目中的应用

1.算法或操作遵循相似的逻辑

2.重构时,把相同的代码抽取到父类中

3.重要、复杂的算法,核心算法设计为模板算法


下面就通过写一个银行办理业务的模板模式:

首先是一个抽象基类:

BankOption.java

public abstract  class BankOption {

protected String name;
public BankOption(String name){
this.name = name;
}
public void templete(){
//1.办理业务
business();
//2.填写单据
writeBills();
//3.等待呼叫
callWait();
//4.窗口办理
windowDeal();
}

/**
* 办理业务
*/
private   void business(){
System.out.println(name + "办理业务");
}

/**
* 填写单据,具体填写说明单据,让用户自己选择
*/
protected abstract void writeBills();

/**
* 等待呼叫
*/
private  void callWait(){
System.out.println(name + "等待呼叫...");
//模拟顾客等待5秒钟
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//5秒后等待结束,可以办理业务了
System.out.println("呼叫" + name + "到窗口办理业务");
}

/**
* 窗口办理
*/
private   void windowDeal(){
System.out.println(name + "窗口办理");
System.out.println("窗口办理中...");
//模拟在窗口办理业务时3秒钟
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(name + "办理业务完成");
}

}


Customer1.java

public class Customer1 extends BankOption{
public Customer1(String name){
super(name);
}
@Override
protected void writeBills() {
System.out.println(name + "填写汇款单据");
}
}


Customer2.java

public class Customer2 extends BankOption{
public Customer2(String name){
super(name);
}
@Override
protected void writeBills() {
System.out.println(name + "填写存款单据");
}
}


Customer3.java

public class Customer3 extends BankOption{
public Customer3(String name){
super(name);
}
@Override
protected void writeBills() {
System.out.println(name + "填写办理银行卡业务");
}
}


Main.java测试类:

public class Main {
public static void main(String[] args) {
BankOption c1 = new Customer1("顾客1");
BankOption c2 = new Customer2("顾客2");
BankOption c3 = new Customer3("顾客3");
c1.templete();
System.out.println("\n*************************");
c2.templete();
System.out.println("*************************");
c3.templete();

}
}


运行结果:

顾客1办理业务

顾客1填写汇款单据

顾客1等待呼叫…

呼叫顾客1到窗口办理业务

顾客1窗口办理

窗口办理中…

顾客1办理业务完成

[b]***************[/b]’

顾客2办理业务

顾客2填写存款单据

顾客2等待呼叫…

呼叫顾客2到窗口办理业务

顾客2窗口办理

窗口办理中…

顾客2办理业务完成

[b]***************[/b]’

顾客3办理业务

顾客3填写办理银行卡业务

顾客3等待呼叫…

呼叫顾客3到窗口办理业务

顾客3窗口办理

窗口办理中…

顾客3办理业务完成

上就是一个简单的银行办理业务的模板方法模式,我们把所以规定了的步奏,1、3、4都写在基类中,这样很好的隐藏了实现细节,顾客只需要填写对应的单据就行了,那么我们可以通过上面的例子再改进下,来理解下上面提到的细节:钩子方法,为什么使用钩子方法呢?上面我们每个用户都模拟了等待呼叫功能,有时候如果另外一个窗口已经是空闲的,就可以直接叫用户去办理业务了,这个时候我们就可以使用钩子方法了,当钩子方法钩上的时候,也就是在本程序中表示,你可以不用等待呼叫,直接去窗口办理业务了,如果没有钩上,就表示你要继续等待,这里就模拟一下,1、3不等待,2等待。通过一下代码比较一下。

BankOption.java中加入一个钩子方法即可

public void templete(){
//1.办理业务
business();
//2.填写单据
writeBills();
//3.等待呼叫
if(isWait())
callWait();
else
System.out.println("不需要等待");
//4.窗口办理
windowDeal();
}
//通过加入这个方法去判断是否需要等待,当然,这里有点不符合实际,
//因为这里是用户去实现是否等待,一般来说我们是银行来控制是否顾客等待,不过只要大家理解钩子方法是什么意思就可以了
protected abstract boolean isWait();


然后每个用户去添加实现钩子方法即可:

Customer1.java

@Override
protected boolean isWait() {
//false表示不需要等待,直接办理窗口
return false;
}


Customer2.java

@Override
protected boolean isWait() {
//表示需要等待
return true;
}


Customer3.java

@Override
protected boolean isWait() {
//不需要等待
return false;
}


运行结果:

顾客1办理业务

顾客1填写汇款单据

不需要等待

顾客1窗口办理

窗口办理中…

顾客1办理业务完成

[b]***************[/b]’

顾客2办理业务

顾客2填写存款单据

顾客2等待呼叫…

呼叫顾客2到窗口办理业务

顾客2窗口办理

窗口办理中…

顾客2办理业务完成

[b]***************[/b]’

顾客3办理业务

顾客3填写办理银行卡业务

不需要等待

顾客3窗口办理

窗口办理中…

顾客3办理业务完成

模板方法模式就介绍到这里,在我们的实际开发应用过程中,模板方法模式应用非常广泛,所以这种设计模式大家一定得掌握。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: