设计模式—模板方法模式

定义

定义一个操作中的算法的框架,而将一些步骤延迟到子类中。使得子类可以不改变一个算法的结构即可重定义改算法的某些特定步骤

场景

有多个子类都有相同的方法但是实现不同,而且有相同的算法步骤,此时可以抽象一个父类来封装子类相同的算法步骤,而每个步骤的具体实现由子类完成

代码

定义父类,约束子类的行为和封装通用的算法步骤

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public abstract class Phone {

protected abstract void turnOn();

protected abstract void sayHello();

protected abstract void playGame();

//不允许overwrite
final public void run() {
this.turnOn();
this.sayHello();
this.playGame();
}

}

定义子类,实现具体的方法逻辑

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class PhoneA extends Phone {

@Override
protected void turnOn() {
System.out.println("A turn on");
}

@Override
protected void sayHello() {
System.out.println("A say hello");
}

@Override
protected void playGame() {
System.out.println("A play game");
}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class PhoneB extends Phone {
@Override
protected void turnOn() {
System.out.println("B turn on");
}

@Override
protected void sayHello() {
System.out.println("B say hello");
}

@Override
protected void playGame() {
System.out.println("B play game");
}
}

测试

1
2
3
4
5
6
7
8
9
10
public class PhoneTest {
@Test
public void testPhone(){
Phone a = new PhoneA();
a.run();
Phone b = new PhoneB();
b.run();
}

}

从上面可以看出 A,B 有相同的行为run(),因此用父类来体现具体的实现

扩展

如果此时需要控制run()中某个行为呢,比如其中的sayHello()方法A需要自己控制执行不执行这个方法,B默认就不执行这个方法,这是可以在父类新增一个方法去控制


父类新增方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public abstract class Phone {

protected abstract void turnOn();

protected abstract void sayHello();

protected abstract void playGame();

//不允许overwrite
final public void run() {
this.turnOn();
//是否sayHello
if (this.isSayHello()) {
this.sayHello();
}
this.playGame();
}

protected boolean isSayHello() {
return true;
}
}

子类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public class PhoneA extends Phone {

private boolean syaHelloFlag= true;

@Override
protected void turnOn() {
System.out.println("A turn on");
}

@Override
protected void sayHello() {
System.out.println("A say hello");
}

@Override
protected void playGame() {
System.out.println("A play game");
}

@Override
protected boolean isSayHello() {
return this.syaHelloFlag;
}

public void setSyaHelloFlag(boolean syaHelloFlag) {
this.syaHelloFlag = syaHelloFlag;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class PhoneB extends Phone {
@Override
protected void turnOn() {
System.out.println("B turn on");
}

@Override
protected void sayHello() {
System.out.println("B say hello");
}

@Override
protected void playGame() {
System.out.println("B play game");
}

@Override
protected boolean isSayHello() {
return false;
}
}

测试

1
2
3
4
5
6
7
8
@Test
public void testPhoneS(){
PhoneA a = new PhoneA();
a.setSyaHelloFlag(false);
a.run();
PhoneB b = new PhoneB();
b.run();
}