初探设计模式之【模版方法】
1. 前言
模板是对多种事物的结构、形式、行为的模板化总结,而模版方法模式(Template Method)则是对一系列类行为(方法)的模式化。我们将总结出来的行为规律固化在基类中,对具体的行为实现则进行抽象化并交给子类去完成,如此便实现了子类的基类模板的套用。
简而言之,通过在基类中,将一套流程固化下来,而将流程中的一个个方法定义为抽象,交由子类去具体实现,当然,也可以实现,相当于给了一个默认实现,子类去按需覆写。
2. 实现
模版方法的实现很好理解,这里快速给出实现。
下面简单以一个人一天的工作内容为例:去公司、打卡、干活、下班。大家去上班都是这样,但是不同角色的人干活却不一样
//抽象工人类 声明了一个模版方法,固化了人们工作的一天。
public abstract class Worker {
public void work() {
goToCompany();
signIn();
doSomething();
offDuty();
}
//去公司
protected abstract void goToCompany();
//打卡
protected abstract void signIn();
//干活
protected abstract void doSomething();
//下班
protected abstract void offDuty();
}
程序员类
public class Programmer extends Worker{
@Override
protected void goToCompany() {
System.out.println("坐地铁去上班");
}
@Override
protected void signIn() {
System.out.println("打卡,迟到2分钟,扣200");
}
@Override
protected void doSomething() {
System.out.println("写bug...");
}
@Override
protected void offDuty() {
System.out.println("程序员加会班再下班");
}
}
CEO 类
public class CEO extends Worker {
@Override
protected void goToCompany() {
System.out.println("坐飞机去公司");
}
@Override
protected void signIn() {
System.out.println("不用打卡");
}
@Override
protected void doSomething() {
System.out.println("骂员工");
}
@Override
protected void offDuty() {
System.out.println("老板下班走人");
}
}
经理
public class Manager extends Worker{
@Override
protected void goToCompany() {
System.out.println("开车去公司");
}
@Override
protected void signIn() {
System.out.println("免打卡");
}
@Override
protected void doSomething() {
System.out.println("教育下属");
}
@Override
protected void offDuty() {
System.out.println("下班");
}
}
然后我们看一下调用处的代码
Worker worker = new Programmer();
worker.work();
worker = new CEO();
worker.work();
worker = new Manager();
worker.work();
如上,每个角色都可以快速的调用实现一样的功能,但到了具体的每件事情上,却又可以都不一样。
坐地铁去上班
打卡,迟到2分钟,扣200
写bug…
程序员加会班再下班坐飞机去公司
不用打卡
骂员工
老板下班走人开车去公司
免打卡
教育下属
下班
3. 总结
需要理解的是:这个固化流程的方法就是模板方法,一般我们可以将这个方法标记为 final ,防止子类复写,修改这套流程。
模版方法模式其实很熟了,只是以前不知道这就是模版方法模式。在 Android 开发中,大家在工程都会抽象出一个 Activity 的基类,在他的 onCreate 中,分别写上 initView、parseData、initData 等方法,这样在我们具体的activity中,就可以不用写 onCreate 方法了,这三个方法含义从其命名上都显而易见了,我们在这三个方法中各司其职,并且由于固化了顺序,就很难再出现没有初始化视图就直接使用了(比如由于疏忽, findViewById 写在了调用的后面),这样就保持了一种相对固定的开发模式,不易于出错。