模板方法模式(行为模式)
1. 模板方法模式介绍
- 父类定义算法骨架,细节的具体实现延迟到子类
- 子类只是定义某些自己的个性化处理,但不改变执行顺序
2. 好处
- 减少代码冗余,共性抽取后算法流程更加清晰与规范
- 降低流程性错误的可能,开发类似的新需求,能通过父类算法骨架清晰理出流程
- 定义了统一执行标准,便于管理与控制流程
- 子类仅需要实现自己的个性化业务,修改自己的业务不会影响其他业务,符合单一职责原则
3. 场景案例
- 项目中会开发大量实时变化的榜单,榜单的更新与查询流程基本都相同,如:公共校验、个性化校验、榜单排名获取、符合规则上榜、不符合规则下榜,但不同榜单校验方式与获取渠道不同
- 使用模板方法模式
- 接口添加为需要的抽象方法
- 抽象类实现接口添加算法骨架与实现统一的抽象方法,同时使用接口的抽象方法
- 具体的榜单需要继承抽象父类,实现抽象方法,然后调用算法骨架方法即可
- 一对一视频聊有三中场景,执行流程均相同,但是计费规则等业务不同
- 抽象父类定义执行顺序
- 三种场景:一对一、直播转向、速配,直接继承父类处理规则,然后实现自己具体的计费规则
4. 案例源码
├── IRank.java
├── base
│ └── AbstractBaseRank.java
├── bean
│ ├── RankDelReq.java
│ └── RankMessageReq.java
├── ext
│ └── ExtServiceImpl.java
└── impl└── RankServiceImpl.java
public interface IRank {int getCommLimit(long userId);int getRankUp(long userId);Double getScore(long userId);boolean doRankUp(RankDelReq rankDelReq);boolean doRankDown(RankDelReq rankDelReq);
}
public abstract class AbstractBaseRank implements IRank {public void dealRank(RankMessageReq rankMessage) {if (rankMessage == null || rankMessage.getUserId() == null) {System.out.println(String.format("传入信息异常:%s", rankMessage));return;}long userId = rankMessage.getUserId();int commLimit = getCommLimit(userId);if (commLimit != 0) {boolean rankDownFlag = doRankDown(new RankDelReq(userId, null, commLimit));System.out.println(String.format("用户:%s 不符合公共判断下榜单:%s 下榜结果:%s", userId, commLimit, rankDownFlag));return;}int rankUpLimit = getRankUp(userId);if (rankUpLimit != 0) {boolean rankDownFlag = doRankDown(new RankDelReq(userId, null, rankUpLimit));System.out.println(String.format("用户:%s 不符合个性化判断下榜单:%s 下榜结果:%s", userId, rankUpLimit, rankDownFlag));return;}Double score = getScore(userId);if (score == null) {boolean rankDownFlag = doRankDown(new RankDelReq(userId, score, null));System.out.println(String.format("用户:%s 没有分数判断下榜单 下榜结果:%s", userId, rankDownFlag));return;}boolean rankUpFlag = doRankUp(new RankDelReq(userId, score, null));System.out.println(String.format("用户:%s 上榜结果:%s", userId, rankUpFlag));}@Overridepublic int getCommLimit(long userId) {if (ExtServiceImpl.isFreeze(userId)) {System.out.println(String.format("用户:%s 被冻结:%s", userId));return 1;}if (ExtServiceImpl.isBan(userId)) {System.out.println(String.format("被禁玩:%s", userId));return 2;}if (ExtServiceImpl.isRankAudit(userId)) {System.out.println(String.format("榜单审核中:%s", userId));return 3;}return 0;}
}
public class RankServiceImpl extends AbstractBaseRank {@Overridepublic int getRankUp(long userId) {System.out.println("个性化判断");return 0;}@Overridepublic Double getScore(long userId) {System.out.println("查询用户在榜单的分数");return 0D;}@Overridepublic boolean doRankUp(RankDelReq rankDelReq) {System.out.println("用户上榜");return true;}@Overridepublic boolean doRankDown(RankDelReq rankDelReq) {System.out.println("用户下榜");return true;}
}
public class RankServiceImplTest {@Testpublic void test() {RankServiceImpl rankServiceImpl = new RankServiceImpl();System.out.println(String.format("用户:%s 榜单处理", 2808253L));rankServiceImpl.dealRank(new RankMessageReq(2808253L));System.out.println();System.out.println(String.format("用户:%s 榜单处理", null));rankServiceImpl.dealRank(new RankMessageReq(null));}
}