申明:
本文章首发自本人博客:https://www.cnblogs.com/wang-meng 和公众号:壹枝花算不算浪漫 如若转载请标明来源html
以前在个人博客(一枝花算不算浪漫)中已经更新过两篇设计模式相关的内容java
上面内容都是基于真实业务场景精简后的设计(工做中真实场景使用到的)。node
以前为了学习设计模式,看过网上不少相关博客讲解,大都是画下UML类图,举例几个绝不相干的demo,看了几遍仍然是云里雾里。设计模式
学习设计模式只有在真正的业务场景去使用才会更好的理解其精髓。这里举例本身工做中电商的业务场景,而后配合一些业务功能的实现,来学会设计模式,使本身的代码更优雅。app
权限功能模块-权限树-删除树上的某个权限ide
先说下大多数人为了实现需求都会作的常规操做,这里举例说明,权限A,其子节点B、C函数
这里若是有个流程图效果会更佳,可是相信你们看到文字也能明白其中的运转流程。学习
这里只是简单地列了下操做的步骤,其实你们可能会作的更好,好比查询、删除 均可以批量去作处理,这里就再也不讨论了。this
经过上面的流程,咱们知道一个方法就能够搞定这几个步骤,只是该方法包含了查询、删除等等逻辑操做,看起来并不精简。url
实现类图
代码实现
这里使用访问者模式 分开一个检查relatePriorityNode的visitor,还有一个removeNode的visitor,若是之后扩展其余操做方式直接增长新的visitor便可。
PriorityNode:
/** * 权限树节点 * @author wangmeng * */ @Data public class PriorityNode { /** * id */ private Long id; /** * 权限编号 */ private String code; /** * 权限URL */ private String url; /** * 权限备注 */ private String priorityComment; /** * 权限类型 */ private Integer priorityType; /** * 父权限id */ private Long parentId; /** * 权限的建立时间 */ private Date gmtCreate; /** * 权限的修改时间 */ private Date gmtModified; /** * 子权限节点 */ private List<PriorityNode> children = new ArrayList<PriorityNode>(); /** * 接收一个权限树访问者 * @param visitor 权限树访问者 */ public void accept(PriorityNodeVisitor visitor) { visitor.visit(this); } }
PriorityNodeVisitor:
/** * 权限树节点的访问者接口 * * @author wangmeng * @blog https://www.cnblogs.com/wang-meng/ * @create 2019-12-01 10:12 **/ public interface PriorityNodeVisitor { /** * 访问权限树节点 * * @param node 权限树节点 */ void visit(PriorityNode node); }
AbstractNodeVisitor:
/** * @author wangmeng * @blog https://www.cnblogs.com/wang-meng/ * @create 2019-12-01 10:26 **/ public abstract class AbstractNodeVisitor implements PriorityNodeVisitor{ private PriorityService priorityService; public AbstractNodeVisitor(PriorityService priorityService) { this.priorityService = priorityService; } @Override public void visit(PriorityNode node) { List<PriorityDTO> priorityDTOList = priorityService.listChildPriorities(node.getId()); if (CollectionUtils.isNotEmpty(priorityDTOList)) { for (PriorityDTO priorityDTO : priorityDTOList) { PriorityNode priorityNode = new PriorityNode(); BeanUtils.copyProperties(priorityDTO, priorityNode); // 使用递归处理 priorityNode.accept(this); } } operateNode(node); } /** * 操做权限树 * @param node 树节点 */ abstract void operateNode(PriorityNode node); }
PriorityNodeRelateCheckVisitor:
/** * 权限树节点的关联检查访问者 * * @author wangmeng * @blog https://www.cnblogs.com/wang-meng/ * @create 2019-12-01 10:19 **/ public class PriorityNodeRelateCheckVisitor extends AbstractNodeVisitor{ /** * 关联检查结果 */ private Boolean relateCheckResult = false; /** * 权限管理模块的service组件 */ private PriorityService priorityService; /** * 角色和权限关系管理模块的DAO组件 */ private RolePriorityRelationshipService rolePriorityRelationshipService; /** * 帐号和权限关系管理模块的Service组件 */ private AccountPriorityRelationshipService accountPriorityRelationshipService; /** * 构造函数 */ public PriorityNodeRelateCheckVisitor(PriorityService priorityService, RolePriorityRelationshipService rolePriorityRelationshipService, AccountPriorityRelationshipService accountPriorityRelationshipService) { super(priorityService); this.priorityService = priorityService; this.rolePriorityRelationshipService = rolePriorityRelationshipService; this.accountPriorityRelationshipService = accountPriorityRelationshipService; } @Override void operateNode(PriorityNode node) { Long nodeId = node.getId(); // 检查权限是否被任何一个角色或者是帐号关联了,若是被任何一个角色或者帐号关联,则relateCheckResult=true int roleRelatedCount = rolePriorityRelationshipService .selectCount(new EntityWrapper<RolePriorityRelationship>().eq("priority_id", nodeId)); if(roleRelatedCount > 0) { this.relateCheckResult = true; } int accountRelatedCount = accountPriorityRelationshipService .selectCount(new EntityWrapper<AccountPriorityRelationship>().eq("priority_id", nodeId)); if(accountRelatedCount > 0) { this.relateCheckResult = true; } this.relateCheckResult = false; } public Boolean getRelateCheckResult() { return relateCheckResult; } }
PriorityNodeRemoveVisitor:
/** * 权限树节点的删除访问者 * * @author wangmeng * @blog https://www.cnblogs.com/wang-meng/ * @create 2019-12-01 10:13 **/ public class PriorityNodeRemoveVisitor extends AbstractNodeVisitor{ private PriorityService priorityService; /** * 构造函数 * @param priorityService 权限service */ public PriorityNodeRemoveVisitor(PriorityService priorityService) { super(priorityService); this.priorityService = priorityService; } @Override void operateNode(PriorityNode node) { // 删除权限 priorityService.deleteById(node.getId()); } }
调用地方 PriorityServiceImpl:
@Override public Boolean removePriority(Long id) { try { // 根据id查询权限 Priority priorityDO = baseMapper.selectById(id); PriorityNode priorityNode = priorityDO.clone(PriorityNode.class); // 检查这个权限以及其下任何一个子权限,是否被角色或者帐号给关联着 PriorityNodeRelateCheckVisitor relateCheckVisitor = new PriorityNodeRelateCheckVisitor( this, rolePriorityRelationshipService, accountPriorityRelationshipService); relateCheckVisitor.visit(priorityNode); Boolean relateCheckResult = relateCheckVisitor.getRelateCheckResult(); if(relateCheckResult) { return false; } // 递归删除当前权限以及其下全部的子权限 PriorityNodeRemoveVisitor removeVisitor = new PriorityNodeRemoveVisitor(this); removeVisitor.visit(priorityNode); } catch (Exception e) { log.error("error", e); return false; } return true; }
申明:
本文章首发自本人博客:https://www.cnblogs.com/wang-meng 和公众号:壹枝花算不算浪漫 如若转载请标明来源
本文章首发自本人博客:https://www.cnblogs.com/wang-meng 和公众号:壹枝花算不算浪漫,如若转载请标明来源!
感兴趣的小伙伴可关注我的公众号:壹枝花算不算浪漫