核心逻辑:
公共代码部分变成架子,可变部分变成抽象方法,对于同类方法,通过继承,然后重写抽象方法即可
目的:使得子类不改变一个算法的结构即可重新定义该算法内部的某些步骤
优缺点:
优点:
1.代码复用:通用部分进入父类,子类实现无需再重复编写
2.结构清晰:子类实现只需要重写某些步骤,主体框架已经定义,即在规则内开发
3.扩展性好:如果需要添加步骤,只需要在父类中添加hook,子类再进行重写即可
缺点:
1.层次变复杂:会引入父类子类,会导致代码层次加深,使系统变复杂
2.违反里氏替换原则:子类没正确重写父类方法,可能导致出错
3.类变多
代码举例:
说明:这里是借用个人工作中当中的一个场景-邮件发送excel账单。因为对于其中一类大致步骤都相同,但是不同的开发习惯不同,所以...
1.定义模板
public abstract class BaseTemplate<T> {
/**
* 举例概述:邮件发送excel账单
* 1.获取一个excel
* 2.表头的写入
* 3.数据的获取
* 4.构建输出流
* 5.邮件发送
*/
final Boolean sendMail(String email, String name, String content, Class<T> clazz) {
if (Objects.isNull(email)) {
return Boolean.FALSE;
}
// 1.获取一个excel
ExcelWriter writer = ExcelUtil.getWriter();
// 2.表头的写入
setHeader(writer, clazz);
// 3.数据的获取
List<T> list = getExportData();
// 4.构建写出流
ByteArrayOutputStream outputStream = buildOutputStream(writer, list);
// 5.邮件的发送
sendEmail(email, name, content, outputStream);
// 6.假设还有后置操作
if (needChangeStatus()) {
changeStatus();
}
return Boolean.TRUE;
}
public void sendEmail(String email, String name, String content, ByteArrayOutputStream outputStream) {
System.out.println("发送邮件到:" + email + ",邮件名为:" + name + ",邮件主题为:" + content);
}
private static <T> ByteArrayOutputStream buildOutputStream(ExcelWriter writer, List<T> list) {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
writer.write(list);
writer.flush(outputStream);
writer.close();
return outputStream;
}
/**
* 写表头
* @param writer 文件写入器
* @param clazz 类
*/
abstract void setHeader(ExcelWriter writer, Class clazz);
/**
* 获取导出数据
* @return
*/
abstract List<T> getExportData();
/**
* 修改某个邮件发送状态
*/
abstract void changeStatus();
Boolean needChangeStatus() {
return false;
}
}
2.模板继承
public class AgentMonthBillSend extends BaseTemplate<BillData>{
@Override
void setHeader(ExcelWriter writer, Class clazz) {
System.out.println("表头设置完成");
}
@Override
List<BillData> getExportData() {
System.out.println("数据获取完成");
return new ArrayList<>();
}
@Override
void changeStatus() {
System.out.println("修改状态完成");
}
@Override
Boolean needChangeStatus() {
// 这里根据需要,如果没后置操作,返回false即可,上面的修改状态抽象方法也就不需要写逻辑
return Boolean.TRUE;
}
}
3.模板的使用
public static void main(String[] args) {
AgentMonthBillSend agentMonthBillSend = new AgentMonthBillSend();
agentMonthBillSend.sendMail("1001", "代理商账单", "芜湖", BillData.class);
}
the next:代理模式