项目中的《访问者模式》

打印 上一主题 下一主题

主题 903|帖子 903|积分 2709

这个模式焦点头脑是将基本的数据对象和对应的操作相互分离。数据对象就只是数据对象,如果想要扩展操作,就扩展对应的visitor。
这种模式下的两次分派

第一次分派,是将对数据对象本身举行分派,可以有差别的实现。
第二次分派,是visitor接收差别的数据对象。
结果就是数据对象接受了visitor,然后visitor中组合了数据对象。
这个项目中的使用场景

对于订单状态,有两个数据载体,一个是数据库已存在的当前的状态,一个是消息推送过来的状态。通过两个载体的状态的组合,能做出响应的动作。
处置惩罚逻辑如下⬇︎⬇︎⬇︎

UML是如许的⬇︎⬇︎⬇︎

现实代码是如许的⬇︎⬇︎⬇︎
DbStatus
  1. package com.xxx.sales.saicorder.outerapp.tmall.message.visitor;
  2. import com.xxx.sales.saicorder.outerapp.tmall.enums.BusinessStatusEnum;
  3. import com.xxx.sales.saicorder.outerapp.tmall.enums.MessageDealWithResultEnum;
  4. /**
  5. * @author Euler
  6. */
  7. public abstract class DbStatus {
  8.     /**
  9.      * 处理结果
  10.      */
  11.     private Integer businessStatus;
  12.     public DbStatus(Integer businessStatus) {
  13.         this.businessStatus = businessStatus;
  14.     }
  15.     private DbStatus() {
  16.     }
  17.     /**
  18.      * 接收天猫状态的visitor
  19.      * @param tmallVisitorStatus
  20.      * @return
  21.      */
  22.     public abstract MessageDealWithResultEnum acceptTmallVisitor(TmallVisitorStatus tmallVisitorStatus);
  23.     /**
  24.      * 将DB记录的处理结果转成BusinessStatusEnum
  25.      * @return
  26.      */
  27.     protected BusinessStatusEnum getBusinessStatus(){
  28.         return BusinessStatusEnum.valueOfCode(businessStatus);
  29.     }
  30. }
复制代码
DbPayedStatus
  1. package com.xxx.sales.saicorder.outerapp.tmall.message.visitor;
  2. import com.xxx.sales.saicorder.outerapp.tmall.enums.MessageDealWithResultEnum;
  3. /**
  4. * db记录已支付
  5. * @author Euler
  6. */
  7. public class DbPayedStatus extends DbStatus{
  8.     public DbPayedStatus(Integer businessStatus) {
  9.         super(businessStatus);
  10.     }
  11.     /**
  12.      * 接收天猫状态的visitor
  13.      *
  14.      * @param tmallVisitorStatus
  15.      *
  16.      * @return
  17.      */
  18.     @Override
  19.     public MessageDealWithResultEnum acceptTmallVisitor(TmallVisitorStatus tmallVisitorStatus) {
  20.         return tmallVisitorStatus.visitDbStatus(this);
  21.     }
  22. }
复制代码
DbCloseStatus
  1. package com.xxx.sales.saicorder.outerapp.tmall.message.visitor;
  2. import com.xxx.sales.saicorder.outerapp.tmall.enums.MessageDealWithResultEnum;
  3. /**
  4. * db记录已关闭
  5. * @author Euler
  6. */
  7. public class DbCloseStatus extends DbStatus{
  8.     public DbCloseStatus(Integer businessStatus) {
  9.         super(businessStatus);
  10.     }
  11.     /**
  12.      * 接收天猫状态的visitor
  13.      *
  14.      * @param tmallVisitorStatus
  15.      *
  16.      * @return
  17.      */
  18.     @Override
  19.     public MessageDealWithResultEnum acceptTmallVisitor(TmallVisitorStatus tmallVisitorStatus) {
  20.         return tmallVisitorStatus.visitDbStatus(this);
  21.     }
  22. }
复制代码
DbChargeOffStatus
  1. package com.xxx.sales.saicorder.outerapp.tmall.message.visitor;
  2. import com.xxx.sales.saicorder.outerapp.tmall.enums.MessageDealWithResultEnum;
  3. /**
  4. * db记录已核销
  5. * @author Euler
  6. */
  7. public class DbChargeOffStatus extends DbStatus{
  8.     public DbChargeOffStatus(Integer businessStatus) {
  9.         super(businessStatus);
  10.     }
  11.     /**
  12.      * 接收天猫状态的visitor
  13.      *
  14.      * @param tmallVisitorStatus
  15.      *
  16.      * @return
  17.      */
  18.     @Override
  19.     public MessageDealWithResultEnum acceptTmallVisitor(TmallVisitorStatus tmallVisitorStatus) {
  20.         return tmallVisitorStatus.visitDbStatus(this);
  21.     }
  22. }
复制代码
TmallVisitorStatus
  1. package com.xxx.sales.saicorder.outerapp.tmall.message.visitor;
  2. import com.xxx.sales.saicorder.outerapp.tmall.enums.BusinessStatusEnum;
  3. import com.xxx.sales.saicorder.outerapp.tmall.enums.MessageDealWithResultEnum;
  4. /**
  5. * 天猫visitor
  6. *
  7. * @author Euler
  8. */
  9. public interface TmallVisitorStatus {
  10.     /**
  11.      * 判断数据库记录是否处理成功
  12.      *
  13.      * @param statusEnum
  14.      *
  15.      * @return
  16.      */
  17.     default boolean dbRecordIsFail(BusinessStatusEnum statusEnum) {
  18.         return BusinessStatusEnum.ABNORMAL.equals(statusEnum) || BusinessStatusEnum.CREATE_ORDER_ABNORMAL.equals(statusEnum);
  19.     }
  20.     /**
  21.      * 访问Db 已支付状态
  22.      *
  23.      * @param dbPayedStatus
  24.      *
  25.      * @return
  26.      */
  27.     MessageDealWithResultEnum visitDbStatus(DbPayedStatus dbPayedStatus);
  28.     /**
  29.      * 访问Db已核销状态
  30.      *
  31.      * @param dbChargeOffStatus
  32.      *
  33.      * @return
  34.      */
  35.     MessageDealWithResultEnum visitDbStatus(DbChargeOffStatus dbChargeOffStatus);
  36.     /**
  37.      * 访问Db 已退款状态
  38.      *
  39.      * @param dbCloseStatus
  40.      *
  41.      * @return
  42.      */
  43.     MessageDealWithResultEnum visitDbStatus(DbCloseStatus dbCloseStatus);
  44. }
复制代码
TmallVisitorPayedStatus
  1. package com.xxx.sales.saicorder.outerapp.tmall.message.visitor;
  2. import com.xxx.sales.saicorder.outerapp.tmall.enums.BusinessStatusEnum;
  3. import com.xxx.sales.saicorder.outerapp.tmall.enums.MessageDealWithResultEnum;
  4. /**
  5. * 天猫已支付状态
  6. * @author Euler
  7. * @date 2022 2022/11/22
  8. */
  9. public class TmallVisitorPayedStatus implements TmallVisitorStatus {
  10.     /**
  11.      * 访问Db 已支付状态
  12.      *
  13.      * @param dbPayedStatus
  14.      *
  15.      * @return
  16.      */
  17.     @Override
  18.     public MessageDealWithResultEnum visitDbStatus(DbPayedStatus dbPayedStatus) {
  19.         BusinessStatusEnum businessStatus = dbPayedStatus.getBusinessStatus();
  20.         // 支付处理失败重试
  21.         if (dbRecordIsFail(businessStatus)) {
  22.             return MessageDealWithResultEnum.NORMAL;
  23.         // 支付处理成功,又来支付成功消息,视为重复消息,清除
  24.         }else{
  25.             return MessageDealWithResultEnum.IS_REPEATED_MESSAGE;
  26.         }
  27.     }
  28.     /**
  29.      * 访问Db已核销状态
  30.      *
  31.      * @param dbChargeOffStatus
  32.      *
  33.      * @return
  34.      */
  35.     @Override
  36.     public MessageDealWithResultEnum visitDbStatus(DbChargeOffStatus dbChargeOffStatus) {
  37.         // 状态已经走到核销,又来已支付的消息。视为延时重复消息,清除
  38.         return MessageDealWithResultEnum.IS_REPEATED_MESSAGE;
  39.     }
  40.     /**
  41.      * 访问Db 已退款状态
  42.      *
  43.      * @param dbCloseStatus
  44.      *
  45.      * @return
  46.      */
  47.     @Override
  48.     public MessageDealWithResultEnum visitDbStatus(DbCloseStatus dbCloseStatus) {
  49.         // 状态已走到关闭,又来已支付消息,视为延时消息,清除
  50.         return MessageDealWithResultEnum.IS_REPEATED_MESSAGE;
  51.     }
  52. }
复制代码
TmallVisitorCloseStatus
  1. package com.xxx.sales.saicorder.outerapp.tmall.message.visitor;
  2. import com.xxx.sales.saicorder.outerapp.tmall.enums.MessageDealWithResultEnum;
  3. /**
  4. *
  5. * 天猫已退款状态
  6. * @author Euler
  7. */
  8. public class TmallVisitorCloseStatus implements TmallVisitorStatus{
  9.     /**
  10.      * 访问Db 已支付状态
  11.      *
  12.      * @param dbPayedStatus
  13.      *
  14.      * @return
  15.      */
  16.     @Override
  17.     public MessageDealWithResultEnum visitDbStatus(DbPayedStatus dbPayedStatus) {
  18.         boolean dbRecordIsFail = dbRecordIsFail(dbPayedStatus.getBusinessStatus());
  19.         // 已支付消息处理失败,订单没有创建成功,不能处理退款的消息
  20.         if (dbRecordIsFail) {
  21.             return MessageDealWithResultEnum.NO_SEQUENCE_MESSAGE;
  22.         // 已支付消息处理成功,可以正常处理退款消息
  23.         }else{
  24.             return MessageDealWithResultEnum.NORMAL;
  25.         }
  26.     }
  27.     /**
  28.      * 访问Db已核销状态
  29.      *
  30.      * @param dbChargeOffStatus
  31.      *
  32.      * @return
  33.      */
  34.     @Override
  35.     public MessageDealWithResultEnum visitDbStatus(DbChargeOffStatus dbChargeOffStatus) {
  36.         // 已核销和已退款是互斥消息,处理了核销,就不能处理退款。(天猫核销后不能在天猫退款)
  37.         return MessageDealWithResultEnum.IS_REPEATED_MESSAGE;
  38.     }
  39.     /**
  40.      * 访问Db 已退款状态
  41.      *
  42.      * @param dbCloseStatus
  43.      *
  44.      * @return
  45.      */
  46.     @Override
  47.     public MessageDealWithResultEnum visitDbStatus(DbCloseStatus dbCloseStatus) {
  48.         boolean dbRecordIsFail = dbRecordIsFail(dbCloseStatus.getBusinessStatus());
  49.         // 退款消息处理失败,再来退款重试消息,正常处理
  50.         if (dbRecordIsFail) {
  51.             return MessageDealWithResultEnum.NORMAL;
  52.         // 退款消息处理成功了,再来退款消息,视为延时重复消息,清除
  53.         }else {
  54.             return MessageDealWithResultEnum.IS_REPEATED_MESSAGE;
  55.         }
  56.     }
  57. }
复制代码
TmallVisitorChargeOffVisitorStatus
  1. package com.xxx.sales.saicorder.outerapp.tmall.message.visitor;
  2. import com.xxx.sales.saicorder.outerapp.tmall.enums.MessageDealWithResultEnum;
  3. /**
  4. * 天猫核销完成状态
  5. * @author Euler
  6. */
  7. public class TmallVisitorChargeOffVisitorStatus implements TmallVisitorStatus {
  8.     /**
  9.      * 访问Db 已支付状态
  10.      *
  11.      * @param dbPayedStatus
  12.      *
  13.      * @return
  14.      */
  15.     @Override
  16.     public MessageDealWithResultEnum visitDbStatus(DbPayedStatus dbPayedStatus) {
  17.         boolean dbRecordIsFail = dbRecordIsFail(dbPayedStatus.getBusinessStatus());
  18.         // 已支付消息处理失败,订单没有创建成功,不能处理核销的消息。消息重回队列
  19.         if (dbRecordIsFail) {
  20.             return MessageDealWithResultEnum.NO_SEQUENCE_MESSAGE;
  21.         // 已支付处理成功,正常处理核销消息
  22.         }else{
  23.             return MessageDealWithResultEnum.NORMAL;
  24.         }
  25.     }
  26.     /**
  27.      * 访问Db已核销状态
  28.      *
  29.      * @param dbChargeOffStatus
  30.      *
  31.      * @return
  32.      */
  33.     @Override
  34.     public MessageDealWithResultEnum visitDbStatus(DbChargeOffStatus dbChargeOffStatus) {
  35.         boolean dbRecordIsFail = dbRecordIsFail(dbChargeOffStatus.getBusinessStatus());
  36.         // 核销处理失败,又来核销重试消息,正常处理
  37.         if (dbRecordIsFail) {
  38.             return MessageDealWithResultEnum.NORMAL;
  39.         // 核销处理成功,又来核销消息,视为重复消息,清除
  40.         }else{
  41.             return MessageDealWithResultEnum.IS_REPEATED_MESSAGE;
  42.         }
  43.     }
  44.     /**
  45.      * 访问Db 已退款状态
  46.      *
  47.      * @param dbCloseStatus
  48.      *
  49.      * @return
  50.      */
  51.     @Override
  52.     public MessageDealWithResultEnum visitDbStatus(DbCloseStatus dbCloseStatus) {
  53.         // 关闭后不在接收核销消息,清除
  54.         return MessageDealWithResultEnum.IS_REPEATED_MESSAGE;
  55.     }
  56. }
复制代码
复杂的状态对应关系就如许解决了。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

数据人与超自然意识

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表