模板方法模式

模板方法模式

模板模式通常又叫模板方法模式(Template Method Pattern),是指定义一个算法的骨架,并允许子类为一个或者多个步骤提供实现

模板方法使得子类可以在不改变算法结构的情况下,重新定义算法的某些步骤。

场景:
 1.一次性实现一个算法的不变的部分,并将可变的行为留给子类来实现
 2.各子类中的公共行为被提取出来并集中到一个公共的父类中,从而避免代码重复

下面以HttpClinet发起一次请求调用第三方接口为例:

拼接请求的url地址-->设置请求的参数-->发送请求-->解析返回的参数

第1步 抽象类 :定义一个算法的骨架

public abstract class AbstractRequestTemplate {

public DataResult invoke(String baseUrl, String methodType) {

//1.拼接请求url地址
String url = getUrl(baseUrl);
//2.封装请求参数
Map<String, Object> params = wrapRequestParams();
//3.执行请求
DataResult response = executeRequest(params, url);
//4.解析返回结果
DataResult result = paraResponse(response);
return result;
}

//拼接请求url地址
protected abstract String getUrl(String baseUrl);

//封装请求参数
protected abstract Map<String, Object> wrapRequestParams();

//3.执行请求
public DataResult executeRequest(Map<String, Object> params, String url) {
return null;
}

//4.解析返回结果
public DataResult paraResponse(DataResult response) {
return null;
}
}

第2步:可变的行为留给子类来实现

实现类1

public class UserCottageDeleteRequest extends AbstractRequestTemplate {
private Long ucId;

public UserCottageDeleteRequest(Long ucId) {
this.ucId = ucId;
}

@Override
protected String getUrl(String baseUrl) {
return baseUrl + "/backend/userAuth/remove";
}

@Override
protected Map<String, Object> wrapRequestParams() {
Map<String, Object> params = new HashMap<>(16);
params.put("ucId", this.ucId.toString());
params.put("opera_id", "userId");
params.put("opera_name", "username");
return params;
}
}

实现类2

public class UserCottageEditRequest extends AbstractRequestTemplate {

private UserCottageEditDto dto;

public UserCottageEditRequest(UserCottageEditDto dto) {
this.dto = dto;
}

@Override
protected String getUrl(String baseUrl) {
return baseUrl + "/backend/userAuth/add";
}

@Override
protected Map<String, Object> wrapRequestParams() {
Map<String, Object> params = new HashMap<>(16);
params.put("ocr_id", dto.getOcrId() + "");
params.put("wx_user_id", dto.getWxUserId() + "");
params.put("zj_customer_id", dto.getZjCustomerId() + "");
params.put("ucID", dto.getUcId() + "");
params.put("card_no", dto.getIdCard());
params.put("userMobile", dto.getUserMobile());
params.put("truename", dto.getTrueName());
params.put("village_id", dto.getVillageId() + "");
params.put("status", dto.getStatus() + "");
params.put("userID", dto.getUserId() + "");
params.put("identity", dto.getIdentity() + "");
params.put("opera_name", ThreadContext.getPortalUser().getTrueName());
params.put("opera_id", ThreadContext.getPortalUser().getId().toString());
return params;
}
}

1.正常情况下,不同的请求地址拼接url的方式是不一样的,所以有具体的子类来实现;

2.每个请求所需要的参数也是不一样的,所以交个子类去实现;

3.请求发送每个子类都基本一样,所以这个可以交给公共的抽象类去实现;

4.每个请求都需要去解析返回来的结果,所以这个交给公共的抽象类来实现;

 

模板模式在JDK源码中的使用

AbstractList 与ArrayList就是模板方法模式的体现,addAll这个方法的源码
public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {

public boolean addAll(int index, Collection<? extends E> c) {
rangeCheckForAdd(index);
boolean modified = false;
for (E e : c) {
add(index++, e);
modified = true;
}
return modified;
}
}


public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable{

public boolean addAll(int index, Collection<? extends E> c) {
rangeCheckForAdd(index);

Object[] a = c.toArray();
int numNew = a.length;
ensureCapacityInternal(size + numNew); // Increments modCount

int numMoved = size - index;
if (numMoved > 0)
System.arraycopy(elementData, index, elementData, index + numNew,numMoved);

System.arraycopy(a, 0, elementData, index, numNew);
size += numNew;
return numNew != 0;
}
}

模板设计模式优缺点

优点:

  1.利用模板方法将相同处理逻辑的代码放到抽象父类中,可以提高代码的复用性;

  2.将不同的代码不同的子类中,通过对子类的扩展增加新的行为,提高代码的扩展性;

  3.把不变的行为写在父类上,去除子类的重复代码,提供了一个很好的代码复用平台,符合开闭原则。

缺点

  1.类数目的增加,每一个抽象类都需要一个子类来实现,这样导致类的个数增加

  2.类数量的增加,间接的增加系统的复杂度

  3.继承关系的缺点,当增加新的抽象方法,所有子类都要实现一遍

  

posted @ 2020-11-25 14:27  好了伤疤忘了痛  阅读(67)  评论(0)    收藏  举报