模板模式
定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
父类:抽象类,将公共的方法写在父类,个性化的内容定义抽象方法由子类去实现。
子类:实体类,集成父类,实现父类的抽象方法。
public abstract class Game {
//模板
public final void play(){
//初始化游戏
System.out.println("游戏开始");
//开始游戏
startPlay();
//结束游戏
System.out.println("游戏结束");
}
abstract void startPlay();
}
public class Football extends Game {
@Override
void startPlay() {
System.out.println("Football Game Started. Teams of 11!");
}
}
public class Basketball extends Game {
@Override
void startPlay() {
System.out.println("Basketball Game Started. Teams of 5! ");
}
}
公众号注册
目前患者有扫医生码注册、搜索关注公众号注册、扫术康码注册、扫音响码注册四种注册方式,可以把注册应该做的公共事情提成一个模板(例如:各种校验、创建用户、入组、创建或更新角色等),把个性化的功能交由子类实现(例如:推送模板消息)。
父类:
public abstract class AbstractPatientRegisterHandler {
public WxBase handle(Map<String, String> param, String fromUserName) throws RemoteException {
Integer groupId = Integer.valueOf(param.get("groupId"));
GroupManage group = groupManageMapper.selectByPrimaryKey(groupId);
//查询会员信息是否存在
User user = userMapper.selectByOpenid(fromUserName);
// 会员未注册
if (user == null) {
//创建用户信息(包括三张表:sys_user,t_user_info,sys_user_role)
Integer userId = sysUserService.registerMember(fromUserName, groupId);
user = userMapper.selectByPrimaryKey(userId);
return register(param, fromUserName, group);
}
// 会员已注册,更新组ID
Integer userId = user.getUserid();
user.setSceneValue(String.valueOf(groupId));
userMapper.updateByPrimaryKeySelective(user);
// 查询患者信息是否存在
PatientInfo patientInfo = patientInfoMapper.selectByPrimaryKey(userId);
// 患者未注册,意味着多次扫医生码,但未点开任意链接注册
if (patientInfo == null) {
return register(param, fromUserName, group);
}
// 根据手机号校验是否自己绑定自己
Integer doctorId = group.getCreateBy();
SysUser sysDoctor = sysUserMapper.selectByDoctorId(Long.valueOf(doctorId));
SysUser sysPatient = sysUserMapper.selectByPrimaryKey(Long.valueOf(userId));
if (sysDoctor.getMobile().equals(sysPatient.getMobile())) {
WxText wxText = new WxText();
wxText.setMsgType(WxUtil.RESP_MESSAGE_TYPE_TEXT);
wxText.setContent("请不要自己绑定自己");
return wxText;
}
//多医生 入组前先查询是否已有组
GroupPatient groupPatientParam = new GroupPatient();
groupPatientParam.setPatientId(userId);
List<GroupPatient> groupPatients = groupPatientMapper.selectList(groupPatientParam);
for (GroupPatient groupPatient : groupPatients) {
//已经在这个组了
if (groupId.equals(groupPatient.getGroupId())) {
return warn(param, fromUserName, group);
}
}
// 到这才是真正的入组
GroupPatient groupPatient = new GroupPatient();
groupPatient.setGroupId(groupId);
groupPatient.setPatientId(userId);
groupPatientMapper.insertSelective(groupPatient);
// 更新用户角色
List<SysUserRole> sysUserRoleList = sysUserRoleMapper.selectByUserId(Long.valueOf(userId));
if (sysUserRoleList.get(0).getRoleId().equals(Long.valueOf(RoleType.PATIENT_UNBOUND_DOCTOR))) {
String role = RoleType.PATIENT;
//更新角色 若生日和性别已录入 且角色不为正常患者,更新为正常患者
sysUserRoleMapper.updateByUserId(Long.valueOf(userId), Long.valueOf(role));
}
// 患者入组且已经完善资料(手机号、姓名、性别、出生日期),推送首关建议和服务宣言(包括im服务宣言和咨询模板)
try {
if (sysPatient.getMobile() != null && patientInfo.getPatientName() != null &&
patientInfo.getPatientSex() != null && patientInfo.getBirthdate() != null) {
// 给患者推送医生关怀和叮嘱,
messageUtil.sendCareMsg(userId, fromUserName, patientInfo.getPatientName(), doctorId, sysDoctor.getUsername());
//给医生推送绑定消息
DoctorInfo doctorInfo = doctorInfoMapper.selectByPrimaryKey(doctorId);
messageUtil.sendMsgDoctorBDTZ(patientInfo.getPatientName(), doctorInfo.getGzhOpenid(), doctorInfo.getDoctorId(), doctorInfo.getDoctorName());
}
} catch (BaqiException e) {
log.error(e.getMessage());
}
return success(param, fromUserName, group);
}
/**
* 未注册消息
*/
public abstract WxBase register(Map<String, String> param, String fromUserName, GroupManage group);
/**
* 错误提醒消息
*/
public abstract WxBase warn(Map<String, String> param, String fromUserName, GroupManage group);
/**
* 处理成功消息
*/
public abstract WxBase success(Map<String, String> param, String fromUserName, GroupManage group);
}
术康注册子类:
public class ScanMealHandler extends AbstractPatientRegisterHandler {
@Override
public WxBase register(Map<String, String> param, String fromUserName, GroupManage group) {
WxText wxText = (WxText) patientSubscribeHandler.handle(param, fromUserName);
JSONObject data = KfTemplateData.setDataText(wxText.getContent());
KfTemplateData body = new KfTemplateData(fromUserName, KfTemplateData.MSG_TYPE_TEXT, data, UserType.PATIENT);
mqSendUtil.send(body);
return newsShukang();
}
@Override
public WxBase warn(Map<String, String> param, String content, GroupManage group) {
return newsShukang();
}
@Override
public WxBase success(Map<String, String> param, String fromUserName, GroupManage group) {
//注册成功
String text = String.format("您成功和%s医生建立了医患关系,愿您在%s医生的帮助下早日康复", group.getGroupName(), group.getGroupName());
JSONObject data = KfTemplateData.setDataText(text);
KfTemplateData body = new KfTemplateData(fromUserName, KfTemplateData.MSG_TYPE_TEXT, data, UserType.PATIENT);
mqSendUtil.send(body);
return newsShukang();
}
public WxNews newsShukang() {
WxNews wxNews = new WxNews();
wxNews.setMsgType(WxUtil.RESP_MESSAGE_TYPE_NEWS);
wxNews.setArticleCount(1);
WxArticle item = new WxArticle();
item.setTitle("同济赤壁医院营养餐");
item.setDescription("科学膳食、合理搭配、营养丰富,促进身体康复。");
item.setUrl(domain + "#/shukang/hospital");
item.setPicUrl("https://aikangclouditer-new." + ossRegion + "/static_image/shipintuisong.jpg");
List<WxArticle> articles = new ArrayList<WxArticle>();
articles.add(item);
wxNews.setArticles(articles);
return wxNews;
}
}
扫医生注册子类:
public class PatientJoinGroupHandler extends AbstractPatientRegisterHandler {
@Override
public WxBase register(Map<String, String> param, String fromUserName, GroupManage group) {
WxText wxText = new WxText();
String content = String.format("欢迎您加入爱康大家庭!" +
"\n您的主管医生%s邀请您成为他的专属服务患者!完成注册,即可获得200积分(近期可兑换鸡蛋等生活用品)," +
"每日登录,按医生处方完成健康管理任务即可获得现金红包!" +
"\n\n点击<a href='" + domain + WxMsgUtil.URL_PATIENT_INDEX +
"'>这里</a>完成注册,享受主管医生%s提供的专业健康管理服务。",
group.getCreateName(), group.getCreateName());
wxText.setMsgType(WxUtil.RESP_MESSAGE_TYPE_TEXT);
wxText.setContent(content);
return wxText;
}
@Override
public WxBase warn(Map<String, String> param, String fromUserName, GroupManage group) {
WxText wxText = new WxText();
String content = String.format("您已经和%s医生建立了医患关系,请勿重复绑定", group.getCreateName());
wxText.setMsgType(WxUtil.RESP_MESSAGE_TYPE_TEXT);
wxText.setContent(content);
return wxText;
}
@Override
public WxBase success(Map<String, String> param, String fromUserName, GroupManage group) {
WxText wxText = new WxText();
String content = String.format("您成功和%s医生建立了医患关系,愿您在%s医生的帮助下早日康复",
group.getCreateName(), group.getCreateName());
wxText.setMsgType(WxUtil.RESP_MESSAGE_TYPE_TEXT);
wxText.setContent(content);
return wxText;
}
}
Java8版模板模式
使用Java8的lambda表达式可以极大的简化代码量,以一开始的Game类为例,首先新建一个公共的Callback接口
public interface Callback<T> {
T call(Object... args);
}
然后将回调方法作为方法的参数传入方法
public class Game {
//模板
public void play(Callback play){
//初始化游戏
System.out.println("游戏开始");
//开始游戏
play.call();
//结束游戏
System.out.println("游戏结束");
}
}
调用
public class TestMain {
public static void main(String[] args) {
Game footBall = new Game();
footBall.play(arg -> {
System.out.println("Football Game Started. Teams of 11!");
return null;
});
}
}
Java8版模板模式在公众号注册中的使用
父类,回调由参数传入,这里传入了3个回调方法,在方法调用时需要实现这3个回调方法
public WxBase scan(Integer groupId, WxBase wxBase,
AkCallback<WxBase> newsCallback, //邀请注册回调
AkCallback<WxBase> warnCallback, //多次扫码,已经在这个组的回调
AkCallback<WxBase> successCallback //入组成功回调
) throws RemoteException {
GroupManage group = groupManageMapper.selectByPrimaryKey(groupId);
//查询会员信息是否存在
User user = userMapper.selectByOpenid(wxBase.getToUserName());
// 会员未注册
if (user == null) {
//创建用户信息(包括三张表:sys_user,t_user_info,sys_user_role)
Integer userId = sysUserService.registerMember(wxBase.getToUserName(), groupId);
user = userMapper.selectByPrimaryKey(userId);
return newsCallback.callback(wxBase, group);
}
// 会员已注册,更新组ID
Integer userId = user.getUserid();
user.setSceneValue(String.valueOf(groupId));
userMapper.updateByPrimaryKeySelective(user);
// 查询患者信息是否存在
PatientInfo patientInfo = patientInfoMapper.selectByPrimaryKey(userId);
// 患者未注册,意味着多次扫医生码,但未点开任意链接注册
if (patientInfo == null) {
return newsCallback.callback(wxBase, group);
}
// 根据手机号校验是否自己绑定自己
Integer doctorId = group.getCreateBy();
SysUser sysDoctor = sysUserMapper.selectByDoctorId(Long.valueOf(doctorId));
SysUser sysPatient = sysUserMapper.selectByPrimaryKey(Long.valueOf(userId));
if (sysDoctor.getMobile().equals(sysPatient.getMobile())) {
return retText(wxBase, "请不要自己绑定自己!");
}
//多医生 入组前先查询是否已有组
GroupPatient groupPatientParam = new GroupPatient();
groupPatientParam.setPatientId(userId);
List<GroupPatient> groupPatients = groupPatientMapper.selectList(groupPatientParam);
for (GroupPatient groupPatient : groupPatients) {
//已经在这个组了
if (groupId.equals(groupPatient.getGroupId())) {
return warnCallback.callback(wxBase, group);
}
}
// 到这才是真正的入组
GroupPatient groupPatient = new GroupPatient();
groupPatient.setGroupId(groupId);
groupPatient.setPatientId(userId);
groupPatientMapper.insertSelective(groupPatient);
// 更新用户角色
List<SysUserRole> sysUserRoleList = sysUserRoleMapper.selectByUserId(Long.valueOf(userId));
if (sysUserRoleList.get(0).getRoleId().equals(Long.valueOf(RoleType.PATIENT_UNBOUND_DOCTOR))) {
String role = RoleType.PATIENT;
//更新角色 若生日和性别已录入 且角色不为正常患者,更新为正常患者
sysUserRoleMapper.updateByUserId(Long.valueOf(userId), Long.valueOf(role));
}
// 患者入组且已经完善资料(手机号、姓名、性别、出生日期),推送首关建议和服务宣言(包括im服务宣言和咨询模板)
try {
if (sysPatient.getMobile()!=null && patientInfo.getPatientName()!=null &&
patientInfo.getPatientSex()!=null && patientInfo.getBirthdate()!=null){
// 给患者推送医生关怀和叮嘱,
messageUtil.sendCareMsg(userId,wxBase.getToUserName(),patientInfo.getPatientName(),doctorId,sysDoctor.getUsername());
//给医生推送绑定消息
DoctorInfo doctorInfo = doctorInfoMapper.selectByPrimaryKey(doctorId);
messageUtil.sendMsgBDTZ(patientInfo.getPatientName(),doctorInfo.getGzhOpenid(),doctorInfo.getDoctorId(),doctorInfo.getDoctorName());
}
} catch (BaqiException e) {
log.error(e.getMessage());
}
return successCallback.callback(wxBase, group);
}
子类,实现了3个回调方法
public WxBase scanDoctor(Integer groupId, WxBase wxBase) throws RemoteException {
return scan(groupId, wxBase, obj->{
GroupManage group = (GroupManage)obj[1];
String text = String.format("欢迎您加入爱康大家庭!" +
"\n您的主管医生%s邀请您成为他的专属服务患者!完成注册,即可获得200积分(近期可兑换鸡蛋等生活用品),每日登录,按医生处方完成健康管理任务即可获得现金红包!" +
"\n\n点击<a href='" + domain + WxMsgUtil.URL_PATIENT_INDEX + "'>这里</a>完成注册,享受主管医生%s提供的专业健康管理服务。",
group.getCreateName(), group.getCreateName());
return retText((WxBase)obj[0], text);
}, obj->{
GroupManage group = (GroupManage)obj[1];
String text = String.format("您已经和%s医生建立了医患关系,请勿重复绑定", group.getCreateName());
return retText((WxBase)obj[0], text);
}, obj->{
GroupManage group = (GroupManage)obj[1];
String text = String.format("您成功和%s医生建立了医患关系,愿您在%s医生的帮助下早日康复", group.getCreateName(), group.getCreateName());
return retText((WxBase)obj[0], text);
});
}