架构师内功心法,职场工作中流程标准化的模板模式详解
一、模板方法的应用场景
模板方法适用于以下应用场景:
- 一次性实现一个算法的不变的部分,并将可变的行为留给子类来实现
- 各子类中的公共行为被提取出来并集中到一个公共的父类中,从而避免代码重复。
现实生活中的模板方法应用场景有填写入职登记表、炒菜流程、大象放进冰箱等
下面以公司的技术培训流程为例:
发布培训通知-->制作培训PPT-->组织员工培训-->现场(远程)培训-->提交培训问卷。我们来创建技术培训 TechnicalTraining 类:
public abstract class TechnicalTraining { protected final void createTraining() {
/**
* 发布培训通知
*/
this.PostNotice();
/**
* 制作培训PPT
*/
this.createPPT();
/**
* 组织员工培训
*/
this.OrganizeTraining();
/**
* 如果有远程培训的话,就支持远程培训
*/
if(needOnline()) {
online();
}
/**
* 现场(远程)培训
*/
this.training();
/**
* 提交培训问卷
*/
this.sumitQuestionnaire();
}
final void PostNotice() {
System.out.println("发布培训通知");
}
final void createPPT() {
System.out.println("制作培训PPT");
}
final void OrganizeTraining() {
System.out.println("组织员工培训");
}
final void training() {
System.out.println("现场(远程)培训");
}
final void sumitQuestionnaire() {
System.out.println("提交培训问卷");
}
//在线培训
abstract void online();
protected boolean needOnline() {
return false;
}
}
上面的代码中有个boolean值的判断,这个是使用的钩子方法,主要目的是用来干预执行流程,使得我们控制行为流程更加灵活,更符合实际业务的要求。 钩子方法的返回值一般为适合条件分支语句的返回值(如boolean、int等)。可以根据自己的业务场景来决定是否需要使用钩子方法。
创建Java培训的类:
public class JavaTraining extends TechnicalTraining { @Override
void online() {
System.out.println("远程培训java相关技术");
}
}
创建数据库培训的类:
public class DatabaseTraining extends TechnicalTraining { private boolean needOnlineFlag = false;
public DatabaseTraining(boolean needOnlineFlag) {
this.needOnlineFlag = needOnlineFlag;
}
@Override
void online() {
System.out.println("远程培训数据库相关技术");
}
@Override
protected boolean needOnline() {
return this.needOnlineFlag;
}
}
测试代码:
public static void main(String[] args) {TechnicalTraining javaTraining = new JavaTraining();
javaTraining.createTraining();
TechnicalTraining databaseTraining = new DatabaseTraining(true);
databaseTraining.createTraining();
}
二、模版模式在源码中的体现
2.1 AbstractList类
先看源代码:
/** * {@inheritDoc}
*
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
abstract public E get(int index);
这个get()方法是一个抽象的方法,那么它的逻辑就是交给子类来进行实现,ArrayList就是AbstractList的子类。来看ArrayList中的get()方法的实现代码:
/** * Returns the element at the specified position in this list.
*
* @param index index of the element to return
* @return the element at the specified position in this list
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
public E get(int index) {
rangeCheck(index);
return elementData(index);
}
同理,有AbstractList就会有AbstractMap和AbstractSet类。
2.2 HttpServlet类
每天都在用的
HttpServlet,它继承自抽象类GenericServlet,有三个方法service()和init()、destory()方法,都是模板方法的抽象实现。来看下源码:
public abstract class GenericServlet implements Servlet, ServletConfig, Serializable { private static final long serialVersionUID = 1L;
private transient ServletConfig config;
public GenericServlet() {
}
public void destroy() {
}
public String getInitParameter(String name) {
return this.getServletConfig().getInitParameter(name);
}
public Enumeration<String> getInitParameterNames() {
return this.getServletConfig().getInitParameterNames();
}
public ServletConfig getServletConfig() {
return this.config;
}
public ServletContext getServletContext() {
return this.getServletConfig().getServletContext();
}
public String getServletInfo() {
return "";
}
public void init(ServletConfig config) throws ServletException {
this.config = config;
this.init();
}
public void init() throws ServletException {
}
public void log(String msg) {
this.getServletContext().log(this.getServletName() + ": " + msg);
}
public void log(String message, Throwable t) {
this.getServletContext().log(this.getServletName() + ": " + message, t);
}
public abstract void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;
public String getServletName() {
return this.config.getServletName();
}
}
三、模板方法的优缺点
优点:
利用模板方法将相同处理逻辑的代码放到抽象父类中,可以提高代码的复用性;
将不同的代码不同的子类中,通过对子类的扩展增加新的行为,提高代码的扩展性;
把不变的行为写在父类上,去除子类的重复代码,提供了一个很好的代码复用平台,符合开闭原则。
缺点:
- 类数目的增加,每一个抽象类都需要一个子类来实现,这样导致类的个数增加;
- 类数量的增加,间接地增加了系统实现的复杂度;
- 继承关系自身缺点,如果父类添加新的抽象方法,所有子类都要改一遍。
以上是 架构师内功心法,职场工作中流程标准化的模板模式详解 的全部内容, 来源链接: utcz.com/z/513858.html