申明: 本文章首發自本人博客: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 和公衆號:壹枝花算不算浪漫,如若轉載請標明來源!
感興趣的小夥伴可關注我的公衆號:壹枝花算不算浪漫