Appearance
模板方法模式
定义
模板方法模式是一种行为设计模式,它定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
使用场景
- 一次性实现一个算法的不变部分,并将可变的行为留给子类来实现。
- 重复的代码在各个子类中的实现基本相同,可以使用模板方法模式来减少重复代码。
- 需要控制子类的扩展,只允许在特定的地方进行扩展。
优点
- 提高了代码的复用性,将公共的代码抽取到父类中,子类只需要实现不同的部分。
- 提高了代码的可维护性,将算法的骨架和具体实现分离,便于维护和扩展。
- 提高了代码的可扩展性,子类可以通过重写父类的方法来扩展算法。
缺点
- 增加了代码的复杂度,父类中定义了算法的骨架,子类需要实现具体步骤,增加了代码的复杂性。
- 子类必须实现父类中定义的所有抽象方法,否则无法实例化子类。
- 父类中的模板方法可能会被修改,影响子类的行为。
代码示例
java
import java.util.Timer;
public abstract class Skill {
// 技能释放前
public abstract boolean before();
// 技能释放中
public abstract void doing(Timer timer);
// 技能释放后
public abstract void after();
// 释放技能
public final boolean release(Timer timer) {
boolean before = before();
if (!before) {
return false;
}
doing(timer);
after();
return true;
}
}
java
import java.util.Timer;
import java.util.TimerTask;
public class XuanFengZhanSkill extends Skill{
private boolean cooling;
private final int coolTime = 2;
public int getCoolTime() {
return coolTime;
}
@Override
public boolean before() {
if (cooling) {
System.out.println("技能旋风斩冷却中...");
return false;
}
return true;
}
@Override
public void doing(Timer timer) {
System.out.println("施放技能旋风斩");
cooling = true;
timer.schedule(new TimerTask() {
@Override
public void run() {
cooling = false;
System.out.println("技能旋风斩冷却完成");
}
}, coolTime * 1000);
}
@Override
public void after() {
System.out.println("技能旋风斩施放结束");
}
}
java
import java.util.Timer;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
public class Client {
public static void main(String[] args) {
Timer timer = new Timer();
Skill skill = new XuanFengZhanSkill();
AtomicInteger count = new AtomicInteger(0);
// 施放技能10秒
ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1);
ScheduledFuture<?> future = executorService.scheduleAtFixedRate(() -> {
boolean release = skill.release(timer);
if (release) {
count.incrementAndGet();
}
}, 0, 800, TimeUnit.MILLISECONDS);
// 10秒后结束
executorService.schedule(() -> {
future.cancel(false);
System.out.printf("技能施放次数: %d\n", count.get());
}, 10, TimeUnit.SECONDS);
// 10秒后中止线程池
executorService.schedule(() -> {
executorService.shutdown();
timer.cancel();
}, 12, TimeUnit.SECONDS);
try {
Thread.sleep(20000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
运行结果:
txt
施放技能旋风斩
技能旋风斩施放结束
技能旋风斩冷却中...
技能旋风斩冷却中...
技能旋风斩冷却完成
施放技能旋风斩
技能旋风斩施放结束
技能旋风斩冷却中...
技能旋风斩冷却中...
技能旋风斩冷却完成
施放技能旋风斩
技能旋风斩施放结束
技能旋风斩冷却中...
技能旋风斩冷却中...
技能旋风斩冷却完成
施放技能旋风斩
技能旋风斩施放结束
技能旋风斩冷却中...
技能旋风斩冷却中...
技能旋风斩冷却完成
施放技能旋风斩
技能旋风斩施放结束
技能施放次数: 5
技能旋风斩冷却完成