外观模式
背景
使用Facade 可以为互相关联在一起的错综复杂的类整理出高层接口(API),其中Facade角色可以让系统对外只有一个简单的接口(API),而且Facade 角色还会考虑到系统内部各个类之间的责任关系和依赖关系,按照正确的顺序调用各个类。
登场角色
Facade 窗口
Facade 角色是代表构成系统的许多其他角色的“简单窗口”。Facade 角色向系统外部提供高层接口(API);
构成系统的许多其他角色
这些角色各自完成自己的工作,它们并不知道Facade 角色。Facade 角色调用其他角色进行工作,但是其他角色不会调用Facade 角色;
Client
负责调用 Facade 角色
类图
示例代码
用户点赞之后的一系列操作可封装成一个Facade
LikeServiceImpl 点赞服务
public class LikeServiceImpl extends ServiceImpl<LikeMapper, Like>
implements LikeService {
@Autowired
private RedisTemplate<String, Object> redisTemplate; // 这里的类型要和config下的redis配置一致
@Autowired
private LikeFacade likeFacade;
@Override
public BaseResponse<Object> likeResponse(LikeRequest likeRequest) {
// 是否已经被点赞
Boolean isLiked = likeRequest.getIsLiked();
// 资源类型
Long type = likeRequest.getType();
// 资源id
Long ownerId = likeRequest.getOwnerId();
// 点赞的用户
Long userId = likeRequest.getUserId();
// 存储点赞用户集合的key
String userKey = LIKE_USER_KEY + type + ":" + ownerId;
// 在hash集合中存储点赞数量的key
String numsKey = LIKE_NUMS_KEY + type + ":" + ownerId;
// 获取指定的hashKey
String hashKey = LikeConstant.hashMap.get(type);
if (StringUtils.isBlank(hashKey)) {
hashKey = LIKE_DEFAULT_NUMS_HASH_KEY;
}
if (!isLiked) {
// 添加点赞用户
redisTemplate.opsForSet().add(userKey, userId);
// 点赞数量加1
Boolean aBoolean = redisTemplate.opsForHash().putIfAbsent(hashKey, numsKey, 1);
// 已经存在了,直接加1即可
if (!aBoolean) {
redisTemplate.opsForHash().increment(hashKey, numsKey, 1);
}
// 统一处理点赞的后续操作
likeFacade.executeFacade(String.valueOf(userId), ownerId, type);
return ResultUtils.success(SuccessCode.LIKE_SUCCESS);
} else {
redisTemplate.opsForSet().remove(userKey, userId);
// 点赞数量减1
redisTemplate.opsForHash().increment(hashKey, numsKey, -1);
return ResultUtils.success(SuccessCode.LIKE_CANCEL);
}
}
}
LikeFacade 点赞之后的操作
@Component
public class LikeFacade {
@Autowired
private ArticleMapper articleMapper;
@Autowired
private CommentMapper commentMapper;
@Autowired
private MessagePushService messagePushService;
@Autowired
private HotRankSender hotRankSender;
// 执行
public void executeFacade(String fromId, Long ownerId, Long type) {
String userId = getUserIdByOwnerId(ownerId, type);
int messageType = 0;
if (type.equals(LIKE_ARTICLE_TYPE)) {
messageType = MESSAGE_LIKE_ARTICLE_TYPE;
}
if (type.equals(LIKE_COMMENT_TYPE)) {
messageType = MESSAGE_LIKE_COMMENT_TYPE;
}
// 发送信息
messagePushService.sendRedDotReminder(fromId, userId, "", ownerId, messageType);
// 热榜的内容
if (LIKE_ARTICLE_TYPE.equals(type)) {
HotRankMessage hotRankMessage = new HotRankMessage();
hotRankMessage.setHotRank(HotRank.HOT_LIKE);
hotRankMessage.setOwnerId(ownerId);
hotRankSender.sendHotRankMessage(hotRankMessage);
}
}
private String getUserIdByOwnerId(Long ownerId, Long type) {
int userId = -1;
if (Objects.equals(type, LIKE_ARTICLE_TYPE)) {
userId = articleMapper.selectUserIdByArticleId(ownerId);
}
if (Objects.equals(type, LIKE_COMMENT_TYPE)) {
userId = commentMapper.selectToIdByOwnerId(ownerId);
}
return String.valueOf(userId);
}
}
功能分析
- Facade 模式可以让复杂的东西看起来很简单,接口(API)变少了,但注意不要让类和方法的调用顺序弄错;
转载自:https://juejin.cn/post/7166973107142393887