模板模式

定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。

父类:抽象类,将公共的方法写在父类,个性化的内容定义抽象方法由子类去实现。

子类:实体类,集成父类,实现父类的抽象方法。

public abstract class Game { //模板public final void play(){//初始化游戏System.out.println("游戏开始");//开始游戏startPlay();//结束游戏System.out.println("游戏结束");}abstract void startPlay();
}
public class Football extends Game {@Overridevoid startPlay() {System.out.println("Football Game Started. Teams of 11!");}
}public class Basketball extends Game {@Overridevoid 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);}// 会员已注册,更新组IDInteger 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 {@Overridepublic 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();}@Overridepublic WxBase warn(Map<String, String> param, String content, GroupManage group) {return newsShukang();}@Overridepublic 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 {@Overridepublic 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;}@Overridepublic 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;}@Overridepublic 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);}// 会员已注册,更新组IDInteger 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);});
}

模板模式实现后端公众号登录功能,Java8版相关推荐

  1. 扫码关注公众号登录系统

    微信开发--扫码关注公众号登录系统 前言 准备阶段 NATAPP 测试账号 工具代码 微信 API 调研阶段 步骤1:注册账号(如果使用测试账号可跳过) 步骤2:了解微信扫码机制 步骤3:了解微信消息 ...

  2. 微信公众号是html页面吗,微信公众号怎么使用页面模板功能?微信公众号页面模板功能怎么使用?...

    软件大小: 56.0 MB 软件版本: 4.0.0 软件类型: 文本处理 查看详情 直接下载 yesky 标签: 微信公众号怎么使用页面模板功能?微信公众号页面模板功能怎么使用?微信公众号后台推出了& ...

  3. 一文快速实现微信公众号支付功能(详细版,建议收藏备用)

    进阶架构精品专题 Mysql优化专题(★★★★) 网络协议专题(★★★★) 其余18大专题,请在主页菜单栏查看 后台回复[加群],获取BAT真实面经 微信支付类型 微信支付实际上有很多种不同的类型,具 ...

  4. 微信公众号赞赏功能指引

    公众号赞赏功能指引 一.赞赏账户开通的条件是什么? 2018年6月6号起,公众号每以同一作者名发表3篇或3篇以上的原创文章,即可创建一个赞赏账户,用于赞赏收款.同一公众号最多可以邀请开通3个赞赏账户. ...

  5. 6 实现微信公众号 自动回复功能

    一 实先自动回复功能的逻辑步骤 1 处理POST类型的控制逻辑,接收XML的数据包: 2 解析XML数据包(获得数据包的消息类型或者是事件类型): 3 拼装我们定义好的消息: 4 包装成XML格式: ...

  6. 一文快速实现微信公众号支付功能

    微信支付类型 微信支付实际上有很多种不同的类型,具体要使用哪一种就需要根据不同的应用场景来选择,官方给出的参考例子: 刷卡支付:用户打开微信钱包的刷卡的界面,商户扫码后提交完成支付. 公众号支付:用户 ...

  7. .NET C#使用微信公众号登录网站

    这篇文章主要介绍了.NET C#使用微信公众号登录网站,教大家利用微信公众号进行网站登录,感兴趣的小伙伴们可以参考一下 适用于:本文适用于有一定微信开发基础的用户 引言:花了300大洋申请了微信公众平 ...

  8. 微信公众号 html5 打赏,微信公众号赞赏功能升级,以后可直接打赏作者了!

    微信公众号可以"直接打赏"作者了. 今天早上7点52分,微信公众号平台正式推送消息称,公众号赞赏升级为"喜欢作者",以后作者可以直接收到读者的赞赏了! 值得一提 ...

  9. 微信 SHA1 签名_微信公众号自动回复功能开发

    微信公众号自动回复功能开发 本篇主要讲解 微信公众号自动回复功能开发,让我们自己去托管公众号回复的功能,这样可以更加灵活的根据公众号收到的信息来制定特定的回复信息,一起来了解吧! 1.注册公众号 如果 ...

最新文章

  1. python画图程序飞机_Python海龟画图工具绘制叮当猫程序
  2. PMCAFF今天摆地摊了,然后……
  3. sklearn自学指南(part15)--广义线性回归
  4. 如何用python绘制灰度直方图_Python Opencv任意形状目标检测并绘制框图实例
  5. python登录交换机执行命令_如何用Python脚本登录到交换机上修改配置?
  6. python 运算符重载_Python 炫技操作:模块重载的五种方法
  7. typecho 全站ajax,Typecho全站启用HTTPS教程
  8. C语言实例解析精粹学习笔记——36(模拟社会关系)
  9. VB6.0 组织json对象并生成json字符串
  10. Python 利用百度 API 进行图像识别
  11. 科学计算机恢复初始化,快速解决Windows 10系统还原一直初始化或卡住的方法!...
  12. html以鼠标为中心放大网页,鼠标滚轮网页放大缩小
  13. Exploratory Data Analysis可视化分析美国天气
  14. FCN全卷积神经网络
  15. 国内图像处理相关期刊
  16. 雨伞16骨好还是24骨好_伞骨什么材质好 晴雨伞骨数越多越好吗
  17. ZZULIOJ1086: ASCII码排序(多实例测试)
  18. 微软远程控制安卓汉化版
  19. 一位AI大佬给算法校招同学的建议:观点篇
  20. 全球与中国磨料水射流切割机市场深度研究分析报告

热门文章

  1. 响应式网站设计(1)-理论
  2. 跨平台应用开发进阶(十二) :uni-app 实现应用桌面图标角标提示及应用跳转
  3. 阿里云研究员马涛:龙蜥社区做对了两件事
  4. 桌面破坏王游戏开发学习笔记总结
  5. 防百度地图上下拖动View
  6. 一文看懂VPS、原生IP、住宅IP有什么不同
  7. 农夫过河(基于C语言)
  8. Proxy代理简单使用
  9. Android之九宫格解锁的实现
  10. linux环境变量设置图解,Ubuntu Linux 各个环境变量配置文件详解, 环境变量PATH设置...